文章

理解网络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 进行授权

热门标签