linux——回射服务器多并发(多进程)
生活随笔
收集整理的這篇文章主要介紹了
linux——回射服务器多并发(多进程)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
多并發(fā)原理如圖,多個客戶端連接一個服務器,無論哪個客戶端發(fā)送數據給服務器,服務器都能把數據準確的返回給這個客戶端。
在socket編程中,socket這種文件描述符被默認設置為阻塞,故而read函數和accept函數時阻塞函數,read函數只有從緩沖區(qū)讀到數據了才返回,否則一直等待,程序一直卡在這個位置;accept函數只要有客戶端連接到服務器就返回,否則一直等待,程序一直卡在這個位置。就很容易出現能發(fā)數據但連不上其他客戶端或者只能連不能發(fā)數據的問題,為避免這種情況的發(fā)生,就需要程序同時檢測有沒有客戶端連接和讀取緩沖區(qū)數據,這里我們就以多進程的方式來實現多并發(fā)。父進程用于連接客戶端,只要有客戶端連接就創(chuàng)建一個進程,用于與服務器通信。
服務器
#include <sys/socket.h> #include <unistd.h> #include <arpa/inet.h> #include <stdio.h> #include <string.h> #include <netinet/in.h> #include <sys/types.h>void do_work(int client_sock,char *ip_addr) {char arr[100]={0};while(1){memset(arr,0,sizeof(arr));int ret=read(client_sock,arr,sizeof(arr));//當客戶端關閉,read函數立即返回0if(ret==0){printf("%s 客戶機已關閉\n",ip_addr);break;}printf("%s :",ip_addr);fputs(arr,stdout);write(client_sock,arr,ret);} }int inter() {int client_sock=0;struct sockaddr_in sock;memset(&sock,0,sizeof(sock));sock.sin_family=AF_INET;sock.sin_port=htons(5188);sock.sin_addr.s_addr=htonl(INADDR_ANY);int sockid=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);const int on=1;if(setsockopt(sockid,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on))<0)//設置端口可重復利用{printf("setsockopt\n");return 0;}if(bind(sockid,(struct sockaddr *)&sock,sizeof(sock))<0){printf("bind\n");return 0;}if(listen(sockid,SOMAXCONN)<0){printf("listen\n");return 0;}struct sockaddr_in other_sock;socklen_t other_socklen=sizeof(other_sock);pid_t pid=0,son_pid=0;while(1){client_sock=accept(sockid,(struct sockaddr *)&other_sock,&other_socklen);//父進程處理與客戶端的連接if(client_sock<0){printf("accept\n");return 0;}char *ip_addr=inet_ntoa(other_sock.sin_addr);printf("ip=%s 已連接\n",ip_addr);pid=fork();//只要有客戶端與服務器連接就創(chuàng)建一個進程if(pid==0)//子進程{close(sockid);//子進程不用sockid需要將其關閉do_work(client_sock,ip_addr);//子進程用于處理與客戶端的收發(fā)數據操作break;}else//父進程{close(client_sock);//父進程不用client_sock需要將其關閉}}close(sockid);return 0; }int main() {inter();return 0; }客戶端
#include <stdio.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h>int main() {struct sockaddr_in sock;memset(&sock,0,sizeof(sock));sock.sin_family=AF_INET;sock.sin_port=htons(5188);sock.sin_addr.s_addr=inet_addr("127.0.0.1");int sockid=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);socklen_t socklen=sizeof(sock);if(connect(sockid,(struct sockaddr *)&sock,socklen)<0){printf("connect\n");return 0;}char send[100]={0};char arr[100]={0};while(1) {fgets(send,sizeof(send),stdin);//從標準輸入獲取數據write(sockid,send,strlen(send));if(strcmp(send,"NULL\n")==0)//輸入NULL退出客戶端{break;}read(sockid,arr,sizeof(arr));fputs(arr,stdout);memset(arr,0,strlen(arr));memset(send,0,strlen(send));}close(sockid);return 0; }多線程方式請點此處
總結
以上是生活随笔為你收集整理的linux——回射服务器多并发(多进程)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python获取硬件信息(硬盘序列号,C
- 下一篇: 安卓手机使用linux(含图形界面)——