// 并发服务器-线程 #include <stdio.h> #include <strings.h> //bzero #include <unistd.h> //close #include <sys/socket.h> //socket #include <netinet/in.h> //struct sockaddr_in #include <arpa/inet.h> //inet_addr #include <string.h> #include <pthread.h> void *recv_send_fun(void *arg) { int sockfd_new = *((int *)arg); char buf[1024] = ""; while (1) { bzero(buf, sizeof(buf)); recv(sockfd_new, buf, sizeof(buf), 0); printf("recv: %s\n", buf); send(sockfd_new, "ok", sizeof("ok"), 0); if (strcmp(buf, "quit") == 0) break; // 如果收到了0长度的数据包,意思客户端断开连接,子进程结束 if (strlen(buf) == 0) break; } return NULL; } int main(int argc, char const *argv[]) { // 1.创建套接字 int sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { perror("socket"); return -1; } // 端口复用 int yes = 1; setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (void *)&yes, sizeof(yes)); // 2.绑定bind struct sockaddr_in my_addr; my_addr.sin_family = AF_INET; my_addr.sin_port = htons(8000); my_addr.sin_addr.s_addr = htonl(INADDR_ANY); // 机器的所有可用IP地址 int ret = bind(sockfd, (struct sockaddr *)&my_addr, sizeof(my_addr)); if (ret != 0) { perror("bind"); return -1; } // 3.监听 int backlog = 10; ret = listen(sockfd, backlog); if (ret < 0) { perror("listen"); return -1; } // 4.提取,等待一个客户端连接 struct sockaddr_in cli_addr; socklen_t len = sizeof(cli_addr); char ip[16] = ""; int sockfd_new = 0; while (1) { // 保证提取到了正确的客户端,而不是被信号打断 while (1) { sockfd_new = accept(sockfd, (struct sockaddr *)&cli_addr, &len); if (sockfd_new > 0) break; } inet_ntop(AF_INET, (void *)&cli_addr.sin_addr, ip, 16); printf("提取到的客户端: %s--->%hu\n", ip, ntohs(cli_addr.sin_port)); // ip port // 5.创建线程 pthread_t pth; pthread_create(&pth, NULL, recv_send_fun, (void *)&sockfd_new); pthread_detach(pth); } // 6.关闭套接字 close(sockfd_new); close(sockfd); return 0; }
标签:addr,int,TCP,并发,new,sockfd,服务器,include,buf From: https://www.cnblogs.com/mengyaoli/p/17902036.html