C语言网络编程:TCP实现多线程实现多客户端
生活随笔
收集整理的這篇文章主要介紹了
C语言网络编程:TCP实现多线程实现多客户端
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
TCP通信的編程模型如下:
TCP通信是必須要有一個服務器,通過accept函數與客戶端socket進行三次握手連接創建的通信描述符與客戶端進行數據傳輸。
此時可以將accept函數的連接設置為多線程形式,輪訓監聽,每獲取到一個客戶端的連接,則創建一個子線程專門用于和該客戶端進行通信。
實現代碼如下:
server.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <errno.h>
#include <pthread.h>
#include <signal.h>#define IP "192.168.102.175"
#define PORT 7000void print_err(char *str, int line, int err_no) {printf("%d, %s :%s\n",line,str,strerror(err_no));_exit(-1);
}/*子線程中先接收從客戶端發來的消息,再發送一個消息給客戶端*/
void *receive(void *pth_arg) {int ret = 0;long cfd = (long)pth_arg;char buf[100] = {0};while(1) {bzero(&buf, sizeof(buf));ret = recv(cfd, &buf, sizeof(buf),0); if (-1 == ret) {print_err("recv failed",__LINE__,errno);}else if (ret > 0)printf("recv from client %s \n",buf);ret = send(cfd,"recv ok\n", sizeof("recv ok\n"), 0);if (-1 == ret) print_err("send failed", __LINE__, errno);}
}int main()
{int skfd = -1, ret = -1;skfd = socket(AF_INET, SOCK_STREAM, 0);if ( -1 == skfd) {print_err("socket failed",__LINE__,errno);}struct sockaddr_in addr;addr.sin_family = AF_INET; //設置tcp協議族addr.sin_port = htons(PORT); //設置端口號addr.sin_addr.s_addr = inet_addr(IP); //設置ip地址ret = bind(skfd, (struct sockaddr*)&addr, sizeof(addr));if ( -1 == ret) {print_err("bind failed",__LINE__,errno);}ret = listen(skfd, 3);if ( -1 == ret ) {print_err("listen failed", __LINE__, errno);}//使用accept阻塞形式得監聽客戶端的發來的連接,并返回通信描述符long cfd = -1;pthread_t id;while (1) {struct sockaddr_in caddr = {0};int csize = sizeof(caddr);cfd = accept(skfd, (struct sockaddr*)&caddr, &csize);if (-1 == cfd) {print_err("accept failed", __LINE__, errno);}//建立連接后打印一下客戶端的ip和端口號printf("cport = %d, caddr = %s\n", ntohs(caddr.sin_port),inet_ntoa(caddr.sin_addr));//使用accept返回到描述符,創建子線程進行數據傳輸int ret = pthread_create(&id,NULL,receive,(void*)cfd);if(-1 == ret) print_err("accept failed", __LINE__, errno); }return 0;
}
客戶端的代碼一樣的,主要是進行數據發送和接收
client1.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <errno.h>
#include <pthread.h>
#include <signal.h>#define IP "192.168.102.175"
#define PORT 7000void print_err(char *str, int line, int err_no) {printf("%d, %s :%s\n",line,str,strerror(err_no));_exit(-1);
}int main()
{int skfd = -1, ret = -1;skfd = socket(AF_INET, SOCK_STREAM, 0);if ( -1 == skfd) {print_err("socket failed",__LINE__,errno);}struct sockaddr_in addr;addr.sin_family = AF_INET; //設置tcp協議族addr.sin_port = htons(PORT); //設置端口號addr.sin_addr.s_addr = inet_addr(IP); //設置ip地址//主動發送連接請求ret = connect(skfd,(struct sockaddr*)&addr, sizeof(addr));if(-1 == ret) print_err("connect failed", __LINE__, errno);char buf[100] = {0};char rec[100] = {0};//客戶端發送消息,并接受從服務端返回的消息while (1) {bzero(&buf, sizeof(buf));scanf("%s",buf);ret = send(skfd,&buf,sizeof(buf), 0);if (-1 == ret) {print_err("send failed", __LINE__, errno);}bzero(&rec, sizeof(recv));ret = recv(skfd, &rec, sizeof(rec), 0);if(-1 == ret) print_err("recv failed", __LINE__, errno);else if(ret > 0) printf("recv from server %s\n",rec);}return 0;
}
client2.c和client1.c一樣,這里需要注意的是我在本機進行測試,所以客戶端建立連接的服務端ip和端口號就和服務端一致。如果是跨網通信(跨局域網),這里需要填寫服務器 所在局域網路由器的公網ip。
這里我們建立兩個客戶端,向與服務端進行通信
編譯運行:
gcc server.c -o server -pthread
gcc client1.c -o client1 -pthread
gcc client2.c -o client2 -pthread
先運行server,再分別運行兩個客戶端
查看服務器的線程個數有三個,一個主線程,兩個子線程
zhang@ubuntu:~/Desktop/cpp_practice$ ps -Tp 24567PID SPID TTY TIME CMD24567 24567 pts/2 00:00:00 server24567 24569 pts/2 00:00:00 server24567 24604 pts/2 00:00:00 server
總結
以上是生活随笔為你收集整理的C语言网络编程:TCP实现多线程实现多客户端的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C语言网络编程:UDP通信实现
- 下一篇: 求一个女生qq网名霸气冷酷