1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > C语言网络编程:TCP实现多线程实现多客户端

C语言网络编程:TCP实现多线程实现多客户端

时间:2019-12-28 14:03:50

相关推荐

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.cclient1.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 TTYTIME CMD24567 24567 pts/2 00:00:00 server24567 24569 pts/2 00:00:00 server24567 24604 pts/2 00:00:00 server

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。