网络编程第一课

ops/2024/11/27 22:17:21/

0voice第一课 https://github.com/0voice

今日学习:网络通信IO

网络通信的核心是通过系统提供的socket套接字实现的。socket和c语言中文件操作的本质类似,在c语言中,通过fopen、fclose、fread、fwrite实现了对文件的操作,socket类似于fopen函数,创建一个文件(即套接字),然后可以往该“文件”中写入相关的内容。socket包含三个参数,分别是协议族、文件类型和协议,返回值为fd,类似于fopen中的文件指针,通过fd对套接字进行io操作。

#include<sys/socket.h>     			//socket所需要的头文件sockfd = socket(AF_INET, SOCK_STREAM, 0);

创建了socket后,需要将该socket和对应的地址进行绑定,通信的本质在于不同的地址之间信息的传送,socket提供了一个接口,现在还需要该接口和某个具体的网络地址进行绑定才可以实现通信。

#include<netinet/in.h>  //socketaddr_in 需要的头文件//   地址需要专用的结构体 struct socketaddr_in 来定义
//   其具体结构如下:struct sockaddr_in {			sin_family;					//协议族sin_port;					//端口struct in_addr sin_addr;	//IP地址
}
struch in_addr{s_addr;
}//在服务器端建立一个socketadd类型的地址
struct socketaddr_in server_addr;
server_addr.family = AF_INET;      					//使用ipv4协议族
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);	//自动获取本机的IP地址,并使用htonl转换格式
server_addr.sin_port = htons(2000);					//要绑定的端口号,使用htons转换

获取到了通信地址和socket的fd后,需要将两个进行绑定。

//bind函数
//三个参数// sockfd : 创建socket后反回的fd号,即要绑定的“文件”
// servaddr: IP地址的指针 注意,要把sockaddr_in的指针类型,转换为socketaddr指针类型
//size: IP地址的大小,该参数可以用来判断属于哪个协议族。bind(sockfd, servaddr, size)

绑定之后,就可以监听该端口的信息了,使用listen函数

进入listen之后,就可以被连接了

//sockfd: 绑定后监听端口的对应的fd
//backlog:确定连接请求队列的长度,达到该数量后,新的请求不再接受。
listen(sockfd, 10);

连接之后,可以收到客户端的发送的信息,但是无法显示出来,所以需要accept函数--用于接收客户端发送的信息

//建立客户端
//返回的新套接字是专门用于和当前连接的客户端通信的,
//所有后续的读写操作都需要通过这个新的套接字进行,而原来的监听套接字(sockfd)继续监听新的连接请求。struct sockaddr_in clientaddr;
int clientfd = accept(sockfd, (struct sockaddr *)&clientaddr, sizeof(clientaddr));accept是阻塞的,即它会一直等待,直到有客户端连接请求。如果没有请求,程序将停留在此函数调用//通过recv()函数来接受信息
//buf:指向接收缓冲区的指针,用于存储从套接字读取到的数据
//len接收缓冲区的大小(以字节为单位)。recv() 会尝试最多读取 len 字节的数据
recv(int sockfd, void *buf, size_t len, int flags);
//返回值
//返回实际接收到的字节数(ssize_t),即读取的数据大小。
//如果返回值为 0,表示连接已关闭(对于流式套接字)。

注意sockfd 和 clientfd 的区别:只要bind之后,只有一个sockfd,代表监听的端口。

但是被监听的端口可能同时有很多客户端发送信息,对于每个服务端,都需要使用accept来重新建立一个socket套接字来传送信息,之后可以基于此fd进行recv和send操作。

int client_fd = accept(sockfd, (struct sockaddr *)&clientaddr, &len);
printf("accept finished!");char buffer[1024];
int count = recv(client_fd, buffer, sizeof(buffer), 0);
printf("recv: %s", buffer);
count = send(client_fd, buffer, count, 0);
print("send: %d", count);

recv更像是c语言文件操作中的fread;而send更像是fwrite函数。

总结:

网络io操作的流程如下:

首先建立socket的fd号,将该fd号与地址和端口进行bind;

服务器端可以根据此fd号对这个端口进行listen监听,并维系一个连接队列;

服务器端使用accept与不同的客户端进行连接,连接成功后生成新的socket的fd号,根据此fd号对其进行读/写(即recv和send)操作。

一些心得:

今天的课程涉及到了计算机网络里tcp相关的内容,操作系统中阻塞相关的内容。这些知识本身并不陌生,之前在课堂也都学习过,知识点都理解,只是上手代码,由于不是特别熟悉,还是有点吃力的,需要每一个函数都要去查,包括参数、返回值之类的,计划2小时学完,其实花了很久来上手,大概四小时左右,代码的实现看了两遍,结合gpt搞懂了。虽然时间久,还是很有成就感的。希望越来越熟悉,加快学习的速度。


http://www.ppmy.cn/ops/137190.html

相关文章

详解Qt之QCache 高速缓存

文章目录 QCache 详解前言什么是 QCache&#xff1f;什么是 LRU 策略&#xff1f;QCache 的构造函数和常用成员函数构造函数1. 默认构造函数2. 指定容量的构造函数 常用成员函数1. insert2. object3. contains4. remove5. clear6. setMaxCost 完整示例代码总结 QCache 详解 前…

林业产品推荐系统:Spring Boot架构设计

3 系统分析 这部分内容虽然在开发流程中处于最开始的环节&#xff0c;但是它对接下来的设计和实现起着重要的作用&#xff0c;因为系统分析结果的好坏&#xff0c;将直接影响后面环节的开展。 3.1可行性研究 影响系统开发的因素有很多&#xff0c;比如开发成本高就不适合开展&a…

使用 PDF API 合并 PDF 文件

内容来源&#xff1a; 如何在 Mac 上合并 PDF 文件 1. 注册与认证 您可以注册一个免费的 ComPDFKit API 帐户&#xff0c;该帐户允许您在 30 天内免费无限制地处理 1,000 多个文档。 ComPDFKit API 使用 JSON Web Tokens 方法进行安全身份验证。从控制面板获取您的公钥和密钥&…

Maven Surefire 插件简介

Maven Surefire 插件是 Maven 构建系统中的一个关键组件&#xff0c;专门用于在构建生命周期中执行单元测试。 它通常与 Maven 构建生命周期的测试阶段绑定&#xff0c;确保所有单元测试在项目编译后和打包前被执行。 最新版本 Maven Surefire 插件的最新版本为 3.5.2。 使…

计算机网络的功能

目录 信息交换 资源共享 分布式处理 可靠性增强 集中管理 信息交换 计算机网络最基本的功能之一是允许不同设备之间的数据通信。这包括电子邮件的发送和接收、即时消息的传递、文件传输等。通过网络&#xff0c;用户可以轻松地与全球各地的其他人进行沟通和协作。 信息交…

Python开源项目月排行 2024年10月

#2024年10月2024年10月12日1OpenHands&#xff08;先前称为OpenDevin&#xff09;是一个基于人工智能的软件开发代理平台&#xff0c;旨在通过AI增强软件开发过程。该平台支持开发者执行各类任务&#xff0c;从代码编写到命令行操作&#xff0c;乃至网页浏览等&#xff0c;如同…

吸猫毛空气净化器哪个好?推荐除猫毛效果好的宠物空气净化器品牌

我家里养了五只猫咪&#xff0c;每天睡醒准备来杯咖啡的时候&#xff0c;总能看见猫毛。最尴尬的是这种现象&#xff0c;哪哪都有。养猫人真的每天都要生活在这个世界里面。平时和猫咪玩耍的时候也没有发现这么多猫毛啊。现在一到冬天不能开窗户&#xff0c;真的超级难受感觉每…

LeetCode 第 425 场周赛 个人题解

Q1. 最小正和子数组 原题链接 Q1. 最小正和子数组 思路分析 签到题&#xff0c;暴力就行 时间复杂度&#xff1a;O(N^2) AC代码 class Solution:def minimumSumSubarray(self, nums: List[int], l: int, r: int) -> int:n len(nums)res -1acc list(accumulate(num…