Linux多進程CS伺服器簡單實現 server端 多進程實現多用戶連接,即每個用戶一個連接,這裡仍然用server將收到的字元串轉大寫後返回給客戶端。 代碼實現 測試結果 可以實現多個客戶端同時連接伺服器,伺服器每接受一個客戶就創建一個子進程,用戶端斷開後,進程由父進程自動回收子進程。 存在問題 ...
Linux多進程CS伺服器簡單實現
server端
- 多進程實現多用戶連接,即每個用戶一個連接,這裡仍然用server將收到的字元串轉大寫後返回給客戶端。
- 代碼實現
#include <stdio.h> #include <string.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <ctype.h> #include <stdlib.h> #include <sys/wait.h> #define SERV_IP "127.0.0.1" #define SERV_PORT 8000 void wait_child(int signo) { while(waitpid(0, NULL, WNOHANG)>0); return; } int main(int argc,char *argv[]) { pid_t pid;//進程ID int sfd, cfd;//接收連接的sfd,和client通訊的cfd struct sockaddr_in serv_addr, clie_addr;//創建伺服器和客戶端結構體 socklen_t clie_addr_len;//客戶端結構體長度 char buf[BUFSIZ], clie_IP[BUFSIZ];//buf存放接收到的數據 int n , i;//讀取的數據數n, 迴圈因數i sfd = Socket(AF_INET, SOCK_STREAM, 0);//創建套接字 bzero(&serv_addr, sizeof(serv_addr));//清零 serv_addr.sin_family = AF_INET;//設置協議族為IPv4 serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); //設置網卡為本地任何有效網卡 //inet_pton(AF_INET, SERV_IP, &serv_addr.sin_addr.s_addr); serv_addr.sin_port = htons(SERV_PORT);//設置埠 bind(sfd, (struct sockaddr * )&serv_addr, sizeof(serv_addr));//設置套接字與sfd關聯 listen(sfd, 128);//設置未完成accept的最大數量.開始監聽. while(1)//迴圈接收客戶端連接 { clie_addr_len = sizeof(clie_addr);//初始化客戶端結構體長度 cfd = accept(sfd, (struct sockaddr *)&clie_addr, &clie_addr_len);//接收客戶端連接 printf("client IP:%s, port:%d\n", inet_ntop(AF_INET, &clie_addr.sin_addr.s_addr, clie_IP, sizeof(clie_IP)), ntohs(clie_addr.sin_port)); pid = fork();//創建新進程 if(pid< 0)//出錯 { perror("fork error"); exit(1); } else if(pid == 0)//子進程 { close(sfd);//子進程中先關閉父進程文件描述符 break; } else if(pid>0)//父進程 { close(cfd);//父進程中先關閉子進程文件描述符 signal(SIGCHLD, wait_child); } } if(pid == 0)//以下是子進程真正的業務處理部分 { while(1)//迴圈處理客戶端業務 { n = read(cfd, buf, sizeof(buf)); if(n == 0)//如果read返回0, 說明客戶端已斷開連接 { close(cfd);//關閉客戶端文件描述符 return 0; } else if(n == -1)//出錯 { perror("read error"); exit(1); } else { write(STDOUT_FILENO, buf, n); for(i= 0; i< n;++i) { buf[i] = toupper(buf[i]); } write(cfd, buf, n); } } } return 0; }
client端
- 連接server端,發送字元串,將受到的字元串列印出來(即:與nc命令功能相同)。
- 代碼實現
#include <stdio.h> #include <string.h> #include <unistd.h> #include <netinet/in.h> #include <arpa/inet.h> #define MAXLINE 8192 #define SERV_PORT 8000 int main(int argc,char *argv[]) { struct sockaddr_in servaddr; char buf[MAXLINE]; int sockfd, n; sockfd = socket(AF_INET, SOCK_STREAM, 0); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr); servaddr.sin_port = htons(SERV_PORT); connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)); while(fgets(buf, MAXLINE, stdin)!=NULL) { write(sockfd, buf, strlen(buf)); n =Read(sockfd, buf, MAXLINE); if(n ==0) { printf("the other side has been closed.\n"); break; } else write(STDOUT_FILENO, buf, n); } close(sockfd); return 0; }
測試結果
- 可以實現多個客戶端同時連接伺服器,伺服器每接受一個客戶就創建一個子進程,用戶端斷開後,進程由父進程自動回收子進程。
存在問題
- 未進行錯誤處理,多用戶連接時,可能會產生干擾。