#include <pthread.h> int pthread_create(pthread_t *tid , const pthread_attr_t *attr , void *(*func)(void *) , void *arg); <span style="white-space:pre"> </span>返回:若成功則爲0 , 若出錯則爲正的Exxx值
pthread_create參數: git
#include <pthread.h> int pthread_join(pthead_t *tid , void **status); 返回:若成功則爲0,若出錯則爲正的Exxx值
#include <pthread.h> int pthread_detach(pthead_t *tid); 返回:若成功則爲0,若出錯則爲正的Exxx值
若是一個線程想讓自身脫離,則調用:pthread_detach(pthread_self());程序員
#include <pthread.h> int pthread_self(void); 返回:調用線程的ID
#include <pthread.h> void pthread_self(void *status); 不返回到調用者
1 /* 2 * config.h 包含該tcp/ip套接字編程所須要的基本頭文件,與server.c client.c位於同一目錄下 3 */ 4 5 #include <stdio.h> 6 #include <stdlib.h> 7 #include <string.h> 8 #include <sys/socket.h> 9 #include <sys/types.h> 10 #include <unistd.h> 11 #include <errno.h> 12 #include <netinet/in.h> 13 #include <netdb.h> 14 #include <arpa/inet.h> 15 #include <pthread.h> 16 17 const int MAX_LINE = 2048; 18 const int PORT = 6001; 19 const int BACKLOG = 10; 20 const int LISTENQ = 6666; 21 const int MAX_CONNECT = 20;
1 /* 2 * 服務器端代碼實現 3 */ 4 5 #include "config.h" 6 7 /*處理接收客戶端消息函數*/ 8 void *recv_message(void *fd) 9 { 10 int sockfd = *(int *)fd; 11 while(1) 12 { 13 char buf[MAX_LINE]; 14 memset(buf , 0 , MAX_LINE); 15 int n; 16 if((n = recv(sockfd , buf , MAX_LINE , 0)) == -1) 17 { 18 perror("recv error.\n"); 19 exit(1); 20 }//if 21 buf[n] = '\0'; 22 //若收到的是exit字符,則表明退出通訊 23 if(strcmp(buf , "byebye.") == 0) 24 { 25 printf("Client closed.\n"); 26 close(sockfd); 27 exit(1); 28 }//if 29 30 printf("\nClient: %s\n", buf); 31 }//while 32 } 33 34 int main() 35 { 36 37 //聲明套接字 38 int listenfd , connfd; 39 socklen_t clilen; 40 //聲明線程ID 41 pthread_t recv_tid , send_tid; 42 43 //定義地址結構 44 struct sockaddr_in servaddr , cliaddr; 45 46 /*(1) 建立套接字*/ 47 if((listenfd = socket(AF_INET , SOCK_STREAM , 0)) == -1) 48 { 49 perror("socket error.\n"); 50 exit(1); 51 }//if 52 53 /*(2) 初始化地址結構*/ 54 bzero(&servaddr , sizeof(servaddr)); 55 servaddr.sin_family = AF_INET; 56 servaddr.sin_addr.s_addr = htonl(INADDR_ANY); 57 servaddr.sin_port = htons(PORT); 58 59 /*(3) 綁定套接字和端口*/ 60 if(bind(listenfd , (struct sockaddr *)&servaddr , sizeof(servaddr)) < 0) 61 { 62 perror("bind error.\n"); 63 exit(1); 64 }//if 65 66 /*(4) 監聽*/ 67 if(listen(listenfd , LISTENQ) < 0) 68 { 69 perror("listen error.\n"); 70 exit(1); 71 }//if 72 73 /*(5) 接受客戶請求,並建立線程處理*/ 74 75 clilen = sizeof(cliaddr); 76 if((connfd = accept(listenfd , (struct sockaddr *)&cliaddr , &clilen)) < 0) 77 { 78 perror("accept error.\n"); 79 exit(1); 80 }//if 81 82 printf("server: got connection from %s\n", inet_ntoa(cliaddr.sin_addr)); 83 84 /*建立子線程處理該客戶連接接收消息*/ 85 if(pthread_create(&recv_tid , NULL , recv_message, &connfd) == -1) 86 { 87 perror("pthread create error.\n"); 88 exit(1); 89 }//if 90 91 /*處理服務器發送消息*/ 92 char msg[MAX_LINE]; 93 memset(msg , 0 , MAX_LINE); 94 while(fgets(msg , MAX_LINE , stdin) != NULL) 95 { 96 if(strcmp(msg , "exit\n") == 0) 97 { 98 printf("byebye.\n"); 99 memset(msg , 0 , MAX_LINE); 100 strcpy(msg , "byebye."); 101 send(connfd , msg , strlen(msg) , 0); 102 close(connfd); 103 exit(0); 104 }//if 105 106 if(send(connfd , msg , strlen(msg) , 0) == -1) 107 { 108 perror("send error.\n"); 109 exit(1); 110 }//if 111 }//while 112 }
1 /* 2 * 客戶端代碼 3 */ 4 #include "config.h" 5 6 /*處理接收服務器消息函數*/ 7 void *recv_message(void *fd) 8 { 9 int sockfd = *(int *)fd; 10 while(1) 11 { 12 char buf[MAX_LINE]; 13 memset(buf , 0 , MAX_LINE); 14 int n; 15 if((n = recv(sockfd , buf , MAX_LINE , 0)) == -1) 16 { 17 perror("recv error.\n"); 18 exit(1); 19 }//if 20 buf[n] = '\0'; 21 22 //若收到的是exit字符,則表明退出通訊 23 if(strcmp(buf , "byebye.") == 0) 24 { 25 printf("Server is closed.\n"); 26 close(sockfd); 27 exit(0); 28 }//if 29 30 printf("\nServer: %s\n", buf); 31 }//while 32 } 33 34 35 int main(int argc , char **argv) 36 { 37 /*聲明套接字和連接服務器地址*/ 38 int sockfd; 39 pthread_t recv_tid , send_tid; 40 struct sockaddr_in servaddr; 41 42 /*判斷是否爲合法輸入*/ 43 if(argc != 2) 44 { 45 perror("usage:tcpcli <IPaddress>"); 46 exit(1); 47 }//if 48 49 /*(1) 建立套接字*/ 50 if((sockfd = socket(AF_INET , SOCK_STREAM , 0)) == -1) 51 { 52 perror("socket error"); 53 exit(1); 54 }//if 55 56 /*(2) 設置連接服務器地址結構*/ 57 bzero(&servaddr , sizeof(servaddr)); 58 servaddr.sin_family = AF_INET; 59 servaddr.sin_port = htons(PORT); 60 if(inet_pton(AF_INET , argv[1] , &servaddr.sin_addr) < 0) 61 { 62 printf("inet_pton error for %s\n",argv[1]); 63 exit(1); 64 }//if 65 66 /*(3) 發送連接服務器請求*/ 67 if( connect(sockfd , (struct sockaddr *)&servaddr , sizeof(servaddr)) < 0) 68 { 69 perror("connect error"); 70 exit(1); 71 }//if 72 73 /*建立子線程處理該客戶連接接收消息*/ 74 if(pthread_create(&recv_tid , NULL , recv_message, &sockfd) == -1) 75 { 76 perror("pthread create error.\n"); 77 exit(1); 78 }//if 79 80 /*處理客戶端發送消息*/ 81 char msg[MAX_LINE]; 82 memset(msg , 0 , MAX_LINE); 83 while(fgets(msg , MAX_LINE , stdin) != NULL) 84 { 85 if(strcmp(msg , "exit\n") == 0) 86 { 87 printf("byebye.\n"); 88 memset(msg , 0 , MAX_LINE); 89 strcpy(msg , "byebye."); 90 send(sockfd , msg , strlen(msg) , 0); 91 close(sockfd); 92 exit(0); 93 }//if 94 if(send(sockfd , msg , strlen(msg) , 0) == -1) 95 { 96 perror("send error.\n"); 97 exit(1); 98 }//if 99 100 101 }//while 102 }