Linux 下 C 網路程式設計之 多執行緒通訊 例項
阿新 • • 發佈:2019-01-31
簡單示例,有不對的地方,歡迎指點。
伺服器端
/* ============================================================================ Name : sockThreadServer.c Author : gaotong Version : Copyright : Your copyright notice Description : Hello World in C, Ansi-style ============================================================================ */ #include <stdio.h> #include <stdlib.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <pthread.h> #include <sys/syscall.h> #include <unistd.h> #include <string.h> #define gettid() syscall(__NR_gettid) //獲得執行緒ID void * handler_conn(void * arg) { char send_str[100]; int client_sock_fd = *(int *) arg; char recv_str[100]; //printf("thread run success \n"); while (1) { read(client_sock_fd, recv_str, 100); //如果對方發來exit 就斷開連線 if (strcmp(recv_str, "exit") == 0) { break; } printf("receive from %d : %s \n", client_sock_fd, recv_str); int id = gettid(); // 得到執行緒ID sprintf(send_str, "這是執行緒:%d,你好,client_sock_fd:%d\n", id, client_sock_fd); if(write(client_sock_fd, send_str, 100) == -1){ perror("send error"); //客戶端關閉連線 break; } printf("我說: %s \n", send_str); } free(arg); puts("斷開連線\n"); close(client_sock_fd); pthread_exit(0); } int main(void) { int * client_sockfd; int server_len, client_len; struct sockaddr_in server_address; struct sockaddr_in client_address; struct sockaddr_in tempaddr; server_address.sin_family = AF_INET; server_address.sin_port = htons(1991); server_address.sin_addr.s_addr = inet_addr("127.0.0.1"); //建立一個socket int sock_fd = socket(AF_INET, SOCK_STREAM, 0); //繫結 bind(sock_fd, (struct sockaddr *) &server_address, sizeof(server_address)); listen(sock_fd, 20); while (1) { pthread_t thread; //每連線一個client 就建立一個執行緒 puts("監聽等待:…………\n"); //client_sockfd 需要作為一個指標,傳給執行緒。以便每個執行緒都能控制自己的連線 client_sockfd = (int *) malloc(sizeof(int)); client_len = sizeof(client_address); //int accept (int socket, struct sockaddr *addr, socklen_t *length_ptr) *client_sockfd = accept(sock_fd, (struct sockaddr *) &client_address, (socklen_t *) &client_len); printf("client connected ! %d \n", *client_sockfd); pthread_create(&thread, NULL, handler_conn, client_sockfd); puts("執行緒建立\n"); } return EXIT_SUCCESS; }
客戶端:
/* ============================================================================ Name : sockThreadClient.c Author : gaotong Version : Copyright : Your copyright notice Description : Hello World in C, Ansi-style ============================================================================ */ #include <stdio.h> #include <stdlib.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <pthread.h> #include <unistd.h> #include <string.h> int client_sockfd; char recv_str[100]; void * getMsg(void * arg){ int test; while( (test =read(client_sockfd, recv_str, 100)) != EOF){ if(test == 0) //伺服器關閉連線 break; if(test == -1) { printf("read error!"); break; } printf("收到伺服器訊息:%s\n",recv_str); } close(client_sockfd); pthread_exit(0); } int main(void) { char char_send[100]; //建立一個socket client_sockfd = socket(AF_INET, SOCK_STREAM , 0); struct sockaddr_in serverAddr; //伺服器地址 serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); serverAddr.sin_family = AF_INET; serverAddr.sin_port = htons(1991); connect(client_sockfd,(struct sockaddr *)&serverAddr, sizeof(serverAddr)); pthread_t pt; pthread_create(&pt, NULL, getMsg, NULL); while(1){ gets(char_send); //從控制檯讀入要傳送的資料 //int send (int socket, void *buffer, size_t size, int flags) if(send(client_sockfd, char_send,sizeof(char_send),0) == -1){ break; } printf("我對伺服器說:%s\n",char_send ); if(strcmp(char_send, "exit") == 0){ // 輸入exit 退出 break; } } close(client_sockfd); return EXIT_SUCCESS; }
執行結果: