博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Linux下C编写基本的多线程socket服务器
阅读量:7107 次
发布时间:2019-06-28

本文共 5751 字,大约阅读时间需要 19 分钟。

不想多说什么,会搜这些东西的都是想看代码的吧。

一开始不熟悉多线程的时候还在想怎么来控制一个线程的结束,后来发现原来有pthread_exit()函数可以直接在线程函数内部调用结束这个线程。

开始还想初始化一个pthread_t thread_fd[MAX]数组来存储开启的线程,然后用一个栈存储那些未分配的数组元素(thread_fd[index]=0)的index,跟缓存的思维相似,不过实在是想多了。

废话不多说,直接上代码,服务器和客户端都已经编译通过,正常运行,有基本的容错能力,不过也只是最基本的。

服务器:

1 /*  2  * multi_thread_socket_server.c  3  *  4  *  Created on: Mar 14, 2014  5  *      Author: nerohwang  6  */  7 #include
8 #include
9 #include
10 #include
//pthread_t , pthread_attr_t and so on. 11 #include
12 #include
//structure sockaddr_in 13 #include
//Func : htonl; htons; ntohl; ntohs 14 #include
//Func :assert 15 #include
//Func :memset 16 #include
//Func :close,write,read 17 #define SOCK_PORT 9988 18 #define BUFFER_LENGTH 1024 19 #define MAX_CONN_LIMIT 512 //MAX connection limit 20 21 static void Data_handle(void * sock_fd); //Only can be seen in the file 22 23 int main() 24 { 25 int sockfd_server; 26 int sockfd; 27 int fd_temp; 28 struct sockaddr_in s_addr_in; 29 struct sockaddr_in s_addr_client; 30 int client_length; 31 32 sockfd_server = socket(AF_INET,SOCK_STREAM,0); //ipv4,TCP 33 assert(sockfd_server != -1); 34 35 //before bind(), set the attr of structure sockaddr. 36 memset(&s_addr_in,0,sizeof(s_addr_in)); 37 s_addr_in.sin_family = AF_INET; 38 s_addr_in.sin_addr.s_addr = htonl(INADDR_ANY); //trans addr from uint32_t host byte order to network byte order. 39 s_addr_in.sin_port = htons(SOCK_PORT); //trans port from uint16_t host byte order to network byte order. 40 fd_temp = bind(sockfd_server,(struct scokaddr *)(&s_addr_in),sizeof(s_addr_in)); 41 if(fd_temp == -1) 42 { 43 fprintf(stderr,"bind error!\n"); 44 exit(1); 45 } 46 47 fd_temp = listen(sockfd_server,MAX_CONN_LIMIT); 48 if(fd_temp == -1) 49 { 50 fprintf(stderr,"listen error!\n"); 51 exit(1); 52 } 53 54 while(1) 55 { 56 printf("waiting for new connection...\n"); 57 pthread_t thread_id; 58 client_length = sizeof(s_addr_client); 59 60 //Block here. Until server accpets a new connection. 61 sockfd = accept(sockfd_server,(struct sockaddr_*)(&s_addr_client),(socklen_t *)(&client_length)); 62 if(sockfd == -1) 63 { 64 fprintf(stderr,"Accept error!\n"); 65 continue; //ignore current socket ,continue while loop. 66 } 67 printf("A new connection occurs!\n"); 68 if(pthread_create(&thread_id,NULL,(void *)(&Data_handle),(void *)(&sockfd)) == -1) 69 { 70 fprintf(stderr,"pthread_create error!\n"); 71 break; //break while loop 72 } 73 } 74 75 //Clear 76 int ret = shutdown(sockfd_server,SHUT_WR); //shut down the all or part of a full-duplex connection. 77 assert(ret != -1); 78 79 printf("Server shuts down\n"); 80 return 0; 81 } 82 83 static void Data_handle(void * sock_fd) 84 { 85 int fd = *((int *)sock_fd); 86 int i_recvBytes; 87 char data_recv[BUFFER_LENGTH]; 88 const char * data_send = "Server has received your request!\n"; 89 90 while(1) 91 { 92 printf("waiting for request...\n"); 93 //Reset data. 94 memset(data_recv,0,BUFFER_LENGTH); 95 96 i_recvBytes = read(fd,data_recv,BUFFER_LENGTH); 97 if(i_recvBytes == 0) 98 { 99 printf("Maybe the client has closed\n");100 break;101 }102 if(i_recvBytes == -1)103 {104 fprintf(stderr,"read error!\n");105 break;106 }107 if(strcmp(data_recv,"quit")==0)108 {109 printf("Quit command!\n");110 break; //Break the while loop.111 }112 printf("read from client : %s\n",data_recv);113 if(write(fd,data_send,strlen(data_send)) == -1)114 {115 break;116 }117 }118 119 //Clear120 printf("terminating current client_connection...\n");121 close(fd); //close a file descriptor.122 pthread_exit(NULL); //terminate calling thread!123 }

外加客户端:

1 /* 2  * socket_client.c 3  * 4  *  Created on: Mar 15, 2014 5  *      Author: nerohwang 6  */ 7 #include
8 #include
9 #include
//pthread_t , pthread_attr_t and so on.10 #include
11 #include
//structure sockaddr_in12 #include
//Func : htonl; htons; ntohl; ntohs13 #include
//Func :assert14 #include
//Func :memset15 #include
//Func :close,write,read16 #define SOCK_PORT 998817 #define BUFFER_LENGTH 102418 int main()19 {20 int sockfd;21 int tempfd;22 struct sockaddr_in s_addr_in;23 char data_send[BUFFER_LENGTH];24 char data_recv[BUFFER_LENGTH];25 memset(data_send,0,BUFFER_LENGTH);26 memset(data_recv,0,BUFFER_LENGTH);27 28 sockfd = socket(AF_INET,SOCK_STREAM,0); //ipv4,TCP29 if(sockfd == -1)30 {31 fprintf(stderr,"socket error!\n");32 exit(1);33 }34 35 //before func connect, set the attr of structure sockaddr.36 memset(&s_addr_in,0,sizeof(s_addr_in));37 s_addr_in.sin_addr.s_addr = inet_addr("127.0.0.1"); //trans char * to in_addr_t38 s_addr_in.sin_family = AF_INET;39 s_addr_in.sin_port = htons(SOCK_PORT);40 41 tempfd = connect(sockfd,(struct sockaddr *)(&s_addr_in),sizeof(s_addr_in));42 if(tempfd == -1)43 {44 fprintf(stderr,"Connect error! \n");45 exit(1);46 }47 48 while(1)49 {50 printf("Please input something you wanna say(input \"quit\" to quit):\n");51 gets(data_send);52 //scanf("%[^\n]",data_send); //or you can also use this53 tempfd = write(sockfd,data_send,BUFFER_LENGTH);54 if(tempfd == -1)55 {56 fprintf(stderr,"write error\n");57 exit(0);58 }59 60 if(strcmp(data_send,"quit") == 0) //quit,write the quit request and shutdown client61 {62 break;63 }64 else65 {66 tempfd = read(sockfd,data_recv,BUFFER_LENGTH);67 assert(tempfd != -1);68 printf("%s\n",data_recv);69 memset(data_send,0,BUFFER_LENGTH);70 memset(data_recv,0,BUFFER_LENGTH);71 }72 }73 74 int ret = shutdown(sockfd,SHUT_WR); //or you can use func close()--
to close the fd75 assert(ret != -1);76 return 0;77 }

 

转载于:https://www.cnblogs.com/nerohwang/p/3602233.html

你可能感兴趣的文章
A guide to this in JavaScript
查看>>
babel插件开发心得
查看>>
简单聊聊Android组件化
查看>>
Java多线程编程笔记之多线程技能
查看>>
浅谈伪共享
查看>>
Clean Code 读书笔记
查看>>
通过 HTTP Session 单点登录解决方案
查看>>
Android热修复之 打补丁原来如此简单
查看>>
Xshell传输文件
查看>>
同城货运主导全新商流体系:智慧物流成胜负关键?
查看>>
[MetalKit]27-Using-MetalKit-part-17使用MetalKit17
查看>>
QPM 之悬浮窗助力性能优化
查看>>
Android组件化专题 - 组件化配置
查看>>
React生命周期详解
查看>>
大数据成神之路-Java高级特性增强(volatile关键字)
查看>>
C进阶 - 内存四驱模型
查看>>
mp3怎么转换成m4r(iPhone铃声制作)
查看>>
使用Envoy 作Sidecar Proxy的微服务模式-3.分布式追踪
查看>>
React
查看>>
以太坊客户端Ethereum Wallet与Geth区别简介
查看>>