1 #include <stdio.h> 2 #include <strings.h> //bzero 3 #include <unistd.h> //close 4 #include <sys/socket.h> //socket 5 #include <netinet/in.h> //struct sockaddr_in 6 #include <arpa/inet.h> //inet_addr 7 #include <string.h> 8 #include <signal.h> 9 #include <sys/types.h> 10 #include <sys/wait.h> 11 #include <stdlib.h> 12 13 void deal_son(int arg) 14 { 15 printf("即将回收子进程资源\n"); 16 wait(NULL); 17 printf("已经回收子进程资源\n"); 18 } 19 20 int main(int argc, char const *argv[]) 21 { 22 // 1.创建套接字 23 int sockfd = socket(AF_INET, SOCK_STREAM, 0); 24 if (sockfd < 0) 25 { 26 perror("socket"); 27 return -1; 28 } 29 // 端口复用 30 int yes = 1; 31 setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (void *)&yes, sizeof(yes)); 32 // 2.绑定bind 33 struct sockaddr_in my_addr; 34 my_addr.sin_family = AF_INET; 35 my_addr.sin_port = htons(8000); 36 my_addr.sin_addr.s_addr = htonl(INADDR_ANY); // 机器的所有可用IP地址 37 int ret = bind(sockfd, (struct sockaddr *)&my_addr, sizeof(my_addr)); 38 if (ret != 0) 39 { 40 perror("bind"); 41 return -1; 42 } 43 // 3.监听 44 int backlog = 10; 45 ret = listen(sockfd, backlog); 46 if (ret < 0) 47 { 48 perror("listen"); 49 return -1; 50 } 51 // 4.提取,等待一个客户端连接 52 struct sockaddr_in cli_addr; 53 socklen_t len = sizeof(cli_addr); 54 char buf[1024] = ""; 55 char ip[16] = ""; 56 int sockfd_new = 0; 57 while (1) 58 { 59 // 保证提取到了正确的客户端,而不是被信号打断 60 while (1) 61 { 62 sockfd_new = accept(sockfd, (struct sockaddr *)&cli_addr, &len); 63 if (sockfd_new > 0) 64 break; 65 } 66 67 inet_ntop(AF_INET, (void *)&cli_addr.sin_addr, ip, 16); 68 printf("提取到的客户端: %s--->%hu\n", ip, ntohs(cli_addr.sin_port)); // ip port 69 70 pid_t pid = fork(); 71 if (pid < 0) 72 close(sockfd_new); 73 else if (pid == 0) 74 { 75 close(sockfd); 76 // 5.循环收发消息 77 while (1) 78 { 79 bzero(buf, sizeof(buf)); 80 recv(sockfd_new, buf, sizeof(buf), 0); 81 printf("接收到%s:%hu--->%s\n", ip, ntohs(cli_addr.sin_port), buf); 82 send(sockfd_new, "ok", sizeof("ok"), 0); 83 if (strcmp(buf, "quit") == 0) 84 break; 85 // 如果收到了0长度的数据包,意思客户端断开连接,子进程结束 86 if (strlen(buf) == 0) 87 break; 88 } 89 _exit(1); 90 } 91 else 92 { 93 close(sockfd_new); 94 // 当子进程结束时,会给父进程发送SIGCHLD信号,父进程收到信号回收资源 95 signal(SIGCHLD, deal_son); // 无阻塞 96 } 97 } 98 99 // 6.关闭套接字 100 close(sockfd_new); 101 close(sockfd); 102 return 0; 103 }
标签:addr,int,TCP,并发,new,sockfd,服务器,include,buf From: https://www.cnblogs.com/mengyaoli/p/17902010.html