?? server_thread.c
字號:
/*該服務器采用的實現方法是多線程,在這里面有一個主線程,用它來臨
聽是否有連接,每當有連接是它就會生成一個子線程來處理客戶端的請求,
處理完后子線程退出*/
#include<string.h>#include<stdlib.h>#include<stdio.h>#include<strings.h>#include<unistd.h>#include<sys/types.h>#include<sys/socket.h>#include<netinet/in.h>#include<arpa/inet.h>#include<pthread.h>#define PORT 1234#define BACKLOG 5#define MAXDATASIZE 1000void process_cli(int connectfd, sockaddr_in client);void *start_routine(void *arg);typedef struct ARG { int connfd;sockaddr_in client;};main(){int listenfd, connectfd;pthread_t thread;ARG *arg;struct sockaddr_in server;struct sockaddr_in client;socklen_t sin_size;if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)//創建套接字{perror("Creating socket failed.");exit(1);}int opt = SO_REUSEADDR;setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));//設置地址可重用bzero(&server, sizeof(server));server.sin_family = AF_INET;server.sin_port = htons(PORT);server.sin_addr.s_addr = htonl(INADDR_ANY);if (bind(listenfd, (struct sockaddr *)&server, sizeof(struct sockaddr)) == -1)//綁定{perror("Bind fail.");exit(1);}if (listen(listenfd, BACKLOG) == -1)//監聽{perror("listen fail");exit(1);}sin_size = sizeof(struct sockaddr_in);while (1){ if ((connectfd = accept(listenfd, (struct sockaddr *)&client, &sin_size)) == -1){ //連接
if (error == EINTR)
continue;perror("accept fail.");exit(1);}arg =(ARG *)malloc(sizeof(ARG));//此時為處理子線程分配一個結構,采用動態分配是為了避免之間的干擾arg->connfd = connectfd;memcpy((void *)&arg->client, &client, sizeof(client));if (pthread_create(&thread, NULL, start_routine, (void *)arg))//每有連接到來就創建一個線程來處理它{perror("Pthread_creart fail.");exit(1);}}close(listenfd);}void process_cli(int connectfd, sockaddr_in clien){int num;char recvbuf[MAXDATASIZE];char sendbuf[MAXDATASIZE];char cli_name[MAXDATASIZE];printf("You got a connection from %s.", inet_ntoa(clien.sin_addr));num = recv(connectfd, cli_name, MAXDATASIZE, 0);
if (num == 0){close(connectfd);printf("Client disconnected.\n");return;}cli_name[num - 1] = '\0';printf("Client's name is %s.\n", cli_name);while (num = recv(connectfd, recvbuf, MAXDATASIZE, 0)){
if (error = EINTR)
continue;recvbuf[num] = '\0';printf("Received client(%s) message:%s", cli_name , recvbuf);int i;for (i=0; i<num-1; i++){sendbuf[i] = recvbuf[num - i - 2];}sendbuf[num - 1] = '\0';send(connectfd, sendbuf, strlen(sendbuf), 0);}close(connectfd);}void *start_routine(void *arg){ARG *info;info = (ARG *)arg;process_cli(info->connfd, info->client);free(arg);pthread_exit(NULL);//子線程處理完后退出來}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -