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 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实现多线程实现多客户端相关推荐

  1. Qt:Qt实现Winsock网络编程—TCP服务端和客户端通信(多线程)

    Qt实现Winsock网络编程-TCP服务端和客户端通信(多线程) 前言 感觉Winsock网络编程的api其实和Linux下网络编程的api非常像,其实和其他编程语言的网络编程都差不太多.博主用Qt ...

  2. C语言网络编程:多路IO select实现多客户端

    文章目录 阻塞式的服务器程序 多线程服务器程序 非阻塞式服务器程序 基于事件响应的服务器程序 事件响应服务器程序的实现`select` 阻塞式的服务器程序 我们接触过最多的最基础的网络通信模型为TCP ...

  3. java socket ip_JAVA 网络编程 TCP/IP、Socket 和协议设计

    [JAVA 网络编程 TCP/IP.Socket 和协议设计] TCP/IP 协议简介 IP 首先我们看 IP(Internet Protocol)协议.IP 协议提供了主机和主机间的通信. 为了完成 ...

  4. C语言网络编程函数与相关结构汇总

    持续更新中- 服务器和客户端的一般流程 服务器端:socket()-->bind( )-->listen()-->accept()-->read()/write()---> ...

  5. C语言网络编程(3)— 通过DNS连接到百度

    C语言网络编程(3)- 通过DNS连接到百度 一.gethostbyname()函数 我们现在认知一台计算机主机通常采用直观可读的名字.例如百度我们会记住 www.baidu.com 而不是他的IP地 ...

  6. java全双工_java网络编程TCP聊天全双工

    我正在实现服务器和客户端之间的简单TCP聊天.我使用多线程,因此服务器和客户端可以同时发送和接收数据(全双工).该程序可以工作,但如果服务器有一个控制台既可以输入发送消息,也可以显示接收消息(对于客户 ...

  7. WinSock API网络编程——TCP/IP协议详解

     WinSock API网络编程--TCP/IP协议(http://www.impcas.ac.cn/usr/lujun/browse.asp?id=winsock_tcp)            ...

  8. 网络编程-TCP/IP协议栈-TCP协议

    TCP协议 TCP协议作用 TCP协议位于协议栈的传输层.当应用层向TCP层发送用于网间传输的,用8字节表示的数据流,TCP则吧数据流分割成适当长度的报文段,最大传输段大小(MSS)通常受到改计算机连 ...

  9. 网络编程-TCP/IP协议栈-IP协议

    协议 协议就是约定的一种规则,例如扑克游戏中约定好的各种规则,2<3<4<5<-等,以此作为游戏规则.当所有人都遵循这个规则,那么久可以不需要任何多余的交流就可以进行游戏,这个 ...

  10. qt android 网络编程实例,QT网络编程Tcp下C/S架构的即时通信实例

    先写一个客户端,实现简单的,能加入聊天,以及加入服务器的界面. #ifndef TCPCLIENT_H #define TCPCLIENT_H #include #include #include # ...

最新文章

  1. 好久没更新日志了啊~!!今天发一个AS3的播放器
  2. matlab把图片转为base64
  3. Question | 网站被黑客扫描撞库该怎么应对防范?
  4. java类验证和装载顺序_Java类的加载机制和双亲委派模型
  5. 构造函数与toString
  6. 使用位运算(与运算)代替%操作
  7. HttpClient 使用证书访问https站点
  8. 视频黑屏检测,时长检测 blackdetect
  9. 不是谁多情,亦不是谁薄情
  10. SSH Agent Forwarding概念与示例
  11. Flex使用ribbit.com的服务给手机发送短信SMS
  12. 工程职业伦理(2018年秋)学堂在线习题
  13. Github Pages + Hugo 搭建个人博客
  14. 项目启动初始化SQL脚本
  15. Keras区分狗和猫
  16. echarts 日历图calender
  17. 浮点运算单元(FPU)是什么?
  18. linux systemtap java,Systemtap 两个实用的小例子
  19. 中小型企业网络架构(一)
  20. html5笔试题dw,网页制作笔试选择题

热门文章

  1. Android 知识杂记(MVP模式)
  2. firebug 的使用
  3. 二叉树的前序,中序,后序的递归、迭代实现
  4. 表格下划线怎么加粗_这招高!Excel签名栏的下划线随列宽变化,是不是感觉牛哄哄的?...
  5. dom vue 加载完 执行_前端面试题——Vue
  6. ORB特征提取算法分析与实现,算法分解
  7. 引导修复_怎么使用bcdrepair引导修复系统【详细步骤】
  8. python自动化之文件处理_Python自动化办公之Word批量转成自定义格式的Excel
  9. 全国计算机二级vfp知识点,全国计算机二级VFP知识点总结
  10. python networkx教程_如何在python中使用networkx绘制有向图?