创建tcp套接字

 1   // int socket(int domain, int type, int protocol); 
 2   //       - 功能:创建一个套接字 
 3   //       - 参数: 
 4   //               - domain: 协议族 
 5   //                       AF_INET : ipv4 
 6   //                       AF_INET6 : ipv6 
 7   //                       AF_UNIX, AF_LOCAL : 本地套接字通信(进程间通信) 
 8   //               - type: 通信过程中使用的协议类型 
 9   //                       SOCK_STREAM : 流式协议 
10   //                       SOCK_DGRAM : 报式协议 
11   //               - protocol : 具体的一个协议。一般写0 
12   //                       - SOCK_STREAM : 流式协议默认使用 TCP 
13   //                       - SOCK_DGRAM : 报式协议默认使用 UDP 
14   //               - 返回值: 
15   //                       - 成功:返回文件描述符,操作的就是内核缓冲区。 
16   //                       - 失败:-1
17   int sockfd = socket(AF_INET, SOCK_STREAM, 0);

绑定

 1   struct sockaddr_in serveraddr;
 2   memset(&serveraddr, 0, sizeof(struct sockaddr_in));
 3   serveraddr.sin_family = AF_INET;
 4   serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
 5   serveraddr.sin_port = htons(2048);
 6 
 7   // int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); // socket命 名
 8   //       - 功能:绑定,将fd 和本地的IP + 端口进行绑定
 9   //       - 参数:
10   //               - sockfd : 通过socket函数得到的文件描述符
11   //               - addr : 需要绑定的socket地址,这个地址封装了ip和端口号的信息
12   //               - addrlen : 第二个参数结构体占的内存大小
13   if(bind(sockfd,(struct sockaddr*)& serveraddr,sizeof(struct sockaddr)) == -1){
14     perror("bind");
15     return -1;
16   }

监听

1   // int listen(int sockfd, int backlog);      // /proc/sys/net/core/somaxconn 
2   //       - 功能:监听这个socket上的连接 
3   //       - 参数: 
4   //               - sockfd : 通过socket()函数得到的文件描述符 
5   //               - backlog : 未连接的和已经连接的和的最大值, 5
6   listen(sockfd, 0);

监听以后客户端就可以连接了

然后阻塞等待客户端连接,创建客户端套接字

 1     struct sockaddr_in clientaddr;
 2     socklen_t len = sizeof(clientaddr);
 3 
 4     // int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); 
 5     //     - 功能:接收客户端连接,默认是一个阻塞的函数,阻塞等待客户端连接 
 6     //     - 参数: 
 7     //             - sockfd : 用于监听的文件描述符 
 8     //             - addr : 传出参数,记录了连接成功后客户端的地址信息(ip,port)
 9     //             - addrlen : 指定第二个参数的对应的内存大小 
10     //     - 返回值: 
11     //             - 成功 :用于通信的文件描述符 
12     //             - -1 : 失败 
13     int clientfd = accept(sockfd, (struct sockaddr *)&clientaddr, &len);

创建线程,接收客户端消息

1     pthread_t thid;
2     pthread_create(&thid, NULL, client_thread, &clientfd);

 

 1 void* client_thread(void* arg){
 2   int clientfd = *(int *)arg;
 3   while (1)
 4   {
 5     char buffer[128] = {0};
 6     int count = recv(clientfd, buffer, 128, 0);
 7     if (count == 0)
 8     {
 9       break;
10     }
11     // 将接收到的消息返回给客户端.
12     send(clientfd, buffer, count, 0);
13     printf("clientfd: %d, count: %d, buffer: %s\n", clientfd, count, buffer);
14   }
15 
16   close(clientfd);
17 }