socket程式設計多執行緒模型
阿新 • • 發佈:2018-12-14
/*問題 1.調整程序內的最大檔案描述符上限 2.執行緒如有共享資料,考慮執行緒同步 3.服務與客戶端執行緒退出時,退出處理 4.系統負載,隨著連結客戶端增加,導致其他執行緒不能及時得到CPU */ /*server.c*/ #include <stdio.h> #include <string.h> #include <netinet/in.h> #include <arp/inet.h> #include <pthread.h> #include "wrap.h"//自己封裝socket出錯處理函式,可檢視本部落格文件 #define MAXLINE 80 #define SERV_PORT 8000 struct s_info{ struct sockaddr_in cliaddr; int connfd; }; void* do_work(void* arg) { int n, i; struct s_info* ts = (struct s_info*)arg; char buf[MAXLINE]; char str[INET_ADDRSTRLEN]; /*可以在建立執行緒前設定執行緒建立屬性,設為分離態*/ /*也可以利用函式設定分離態*/ pthread_detach(pthread_self()); while(1){ n=Read(ts->connfd,buf, MAXLINE); if(n==0){ printf("the other side has benn closed.\n"); break; } printf("received from %s at PORT %d\n", inet_ntop(AF_INET, &(*ts).cliaddr.sin_addr, str, sizeof(str)),ntohs((*ts).cliaddr.sin_port)); for(i=0; i<n; i++) { buf[i]=toupper(buf[i]); } Write(ts->connfd,buf,n); } Close(ts->connfd); } int main(void) { struct sockaddr_in servaddr, cliaddr; socklen_t cliaddr_len; int listenfd, connfd; int i=0; pthread_t tid; struct s_info ts[383]; listenfd = Socket(AF_INET, SOCK_STREAM, 0); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(SERV_PORT); Bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)); Listen(listenfd, 20); printf("Accepting connections...\n"); while(1){ cliaddr_len= sizeof(cliaddr); connfd = Accepting(listenfd, (struct sockaddr*)&cliaddr, &cliaddr_len); ts[i].cliaddr = cliaddr; ts[i].connfd = connfd; /*達到執行緒最大數時,pthread_create出錯處理,增加伺服器穩定性*/ pthread_create(&tid, NULL, do_work, (void*)&ts[i]); i++; } return 0; } /* client.c */ #include <stdio.h> #include <string.h> #include <unistd.h> #include <netinet/in.h> #include "wrap.h" #define MAXLINE 80 #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, strlen(buf)); if(n == 0) printf("the other side has been closed.\n"); else Write(STDOUT_FILENO, buf, n); } Close(sockfd); return 0; }