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实现多线程实现多客户端相关推荐
- Qt:Qt实现Winsock网络编程—TCP服务端和客户端通信(多线程)
Qt实现Winsock网络编程-TCP服务端和客户端通信(多线程) 前言 感觉Winsock网络编程的api其实和Linux下网络编程的api非常像,其实和其他编程语言的网络编程都差不太多.博主用Qt ...
- C语言网络编程:多路IO select实现多客户端
文章目录 阻塞式的服务器程序 多线程服务器程序 非阻塞式服务器程序 基于事件响应的服务器程序 事件响应服务器程序的实现`select` 阻塞式的服务器程序 我们接触过最多的最基础的网络通信模型为TCP ...
- java socket ip_JAVA 网络编程 TCP/IP、Socket 和协议设计
[JAVA 网络编程 TCP/IP.Socket 和协议设计] TCP/IP 协议简介 IP 首先我们看 IP(Internet Protocol)协议.IP 协议提供了主机和主机间的通信. 为了完成 ...
- C语言网络编程函数与相关结构汇总
持续更新中- 服务器和客户端的一般流程 服务器端:socket()-->bind( )-->listen()-->accept()-->read()/write()---> ...
- C语言网络编程(3)— 通过DNS连接到百度
C语言网络编程(3)- 通过DNS连接到百度 一.gethostbyname()函数 我们现在认知一台计算机主机通常采用直观可读的名字.例如百度我们会记住 www.baidu.com 而不是他的IP地 ...
- java全双工_java网络编程TCP聊天全双工
我正在实现服务器和客户端之间的简单TCP聊天.我使用多线程,因此服务器和客户端可以同时发送和接收数据(全双工).该程序可以工作,但如果服务器有一个控制台既可以输入发送消息,也可以显示接收消息(对于客户 ...
- WinSock API网络编程——TCP/IP协议详解
WinSock API网络编程--TCP/IP协议(http://www.impcas.ac.cn/usr/lujun/browse.asp?id=winsock_tcp) ...
- 网络编程-TCP/IP协议栈-TCP协议
TCP协议 TCP协议作用 TCP协议位于协议栈的传输层.当应用层向TCP层发送用于网间传输的,用8字节表示的数据流,TCP则吧数据流分割成适当长度的报文段,最大传输段大小(MSS)通常受到改计算机连 ...
- 网络编程-TCP/IP协议栈-IP协议
协议 协议就是约定的一种规则,例如扑克游戏中约定好的各种规则,2<3<4<5<-等,以此作为游戏规则.当所有人都遵循这个规则,那么久可以不需要任何多余的交流就可以进行游戏,这个 ...
- qt android 网络编程实例,QT网络编程Tcp下C/S架构的即时通信实例
先写一个客户端,实现简单的,能加入聊天,以及加入服务器的界面. #ifndef TCPCLIENT_H #define TCPCLIENT_H #include #include #include # ...
最新文章
- 好久没更新日志了啊~!!今天发一个AS3的播放器
- matlab把图片转为base64
- Question | 网站被黑客扫描撞库该怎么应对防范?
- java类验证和装载顺序_Java类的加载机制和双亲委派模型
- 构造函数与toString
- 使用位运算(与运算)代替%操作
- HttpClient 使用证书访问https站点
- 视频黑屏检测,时长检测 blackdetect
- 不是谁多情,亦不是谁薄情
- SSH Agent Forwarding概念与示例
- Flex使用ribbit.com的服务给手机发送短信SMS
- 工程职业伦理(2018年秋)学堂在线习题
- Github Pages + Hugo 搭建个人博客
- 项目启动初始化SQL脚本
- Keras区分狗和猫
- echarts 日历图calender
- 浮点运算单元(FPU)是什么?
- linux systemtap java,Systemtap 两个实用的小例子
- 中小型企业网络架构(一)
- html5笔试题dw,网页制作笔试选择题
热门文章
- Android 知识杂记(MVP模式)
- firebug 的使用
- 二叉树的前序,中序,后序的递归、迭代实现
- 表格下划线怎么加粗_这招高!Excel签名栏的下划线随列宽变化,是不是感觉牛哄哄的?...
- dom vue 加载完 执行_前端面试题——Vue
- ORB特征提取算法分析与实现,算法分解
- 引导修复_怎么使用bcdrepair引导修复系统【详细步骤】
- python自动化之文件处理_Python自动化办公之Word批量转成自定义格式的Excel
- 全国计算机二级vfp知识点,全国计算机二级VFP知识点总结
- python networkx教程_如何在python中使用networkx绘制有向图?