理解网络io
什么是网络IO
Socket FD(File Descriptor)是用来标识网络IO与管理网络连接的。在linux中,它仅仅代表一个整数,用来表示当前创建的IO的编号,是在从0开始依次增加。0是标准输入:stdin,1是标准输出:stdout,2是标准错误:stderr。 如下图在客户端连接服务端的时候,服务端创建一个监听的fd等待客户端的连接,在listenfd收到连接请求后,服务端会创建一个用于与客户端通信的fd来进行数据传输。
下面我将创建一个server端的网络IO来进行实验。
网络IO的基本应用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//创建一个fd,AF_INET表示地址簇,表示使用的协议为IPV4
//SOCK_STREAM表示套接字类型,这里是流式属于TCP,SOCK_DGRAM是套接字
//0代表协议类型为默认(即前两个类型推断后得出)。
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
//存储服务器地址与端口号的结构体
struct sockaddr_in servaddr;
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);// 0.0.0.0
servaddr.sin_port = htons(2000);
//将fd与IP地址与端口号绑定,准备开始监听
if(-1 == bind(sockfd, (struct sockaddr*)&servaddr, sizeof(struct sockaddr))){
printf("bind failed: %s\n",strerror(errno));
return -1;
}
//开始监听,请求队列最大为10
listen(sockfd,10);
//创建客户端的地址。
struct sockaddr_in clientaddr;
socklen_t len = sizeof(clientaddr);
while(1){
//新的sockfd接受刚刚监听到的fd,并与其建立连接
int clientfd = accept(sockfd,(struct sockaddr*)&clientaddr, &len);
//这里用多线程来处理各个连接
pthread_t thid;
pthread_create(&thid, NULL, client_thread, &clientfd);
}
回调函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void *client_thread(void *arg){
int clientfd = *(int *)arg;
while(1){
char buffer[1024] = {0};
//读取传过来的信息到buffer中
int count = recv(clientfd,buffer,1024,0);
//处理连接断开的情况
if(count == 0){
printf("client disconnect %d\n",clientfd);
close(clientfd);
break;
}
printf("RECV: %s\n",buffer);
//将buffer中的信息发给客户端
count = send(clientfd,buffer,count,0);
}
}
本文由作者按照 CC BY 4.0 进行授权
