之前在学习关于网络tcp和多线程的编程,学了知识以后不用一下总绝对心虚,于是就编写了一个基于tcp和多线程的多人聊天室。

具体的实现过程:

服务器端:绑定socket对象->设置监听数->等待连接->有客户端连接就新建一个线程,这个线程中,一旦就收到这个客户发送的消息,就广播的向其他客户端发送同样的消息。

客户端:向客户端连接->新建线程用来接收服务器端发送的消息,同时主进程用来发送消息

话不多说,直接上代码

1 #include

2 #include

3 #include

4 #include

5 #include

6 #include

7 #include

8 #include

9 #include

10

11 typedef struct sockaddr *sockaddrp;12

13 //存储客户端地址的结构体数组

14 struct sockaddr_in src_addr[50];15 socklen_t src_len = sizeof(src_addr[0]);16

17

18

19 //连接后记录confd数组

20 int confd[50] ={};21

22

23 //设置连接人数

24 int count = 0;25

26

27 void *broadcast(void *indexp)28 {29 int index = *(int *)indexp;30 char buf_rcv[255] ={};31 char buf_snd[255] ={};32 //第一次读取用户姓名

33 char name[20] ={};34 int ret = recv(confd[index],name,sizeof(name),0);35 if(0 >ret)36 {37 perror("recv");38 close(confd[index]);39 return;40 }41

42 while(1)43 {44 bzero(buf_rcv,sizeof(buf_rcv));45 recv(confd[index],buf_rcv,sizeof(buf_rcv),0);46

47 //判断是否退出

48 if(0 == strcmp("quit",buf_rcv))49 {50 sprintf(buf_snd,"%s已经退出悟空聊天室",name);51 for(int i = 0;i <= count;i++)52 {53 if(i == index || 0 ==confd[i])54 {55 continue;56 }57

58 send(confd[i],buf_snd,strlen(buf_snd),0);59 }60 confd[index] = -1;61 pthread_exit(0);62

63 }64

65

66 sprintf(buf_snd,"%s:%s",name,buf_rcv);67 printf("%s\n",buf_snd);68 for(int i = 0;i <= count;i++)69 {70 if(i == index || 0 ==confd[i])71 {72 continue;73 }74

75 send(confd[i],buf_snd,sizeof(buf_snd),0);76 }77

78 }79

80 }81

82

83

84

85

86 int main(int argc,char **argv)87 {88 printf("悟空聊天室服务器端开始运行\n");89

90

91 //创建通信对象

92 int sockfd = socket(AF_INET,SOCK_STREAM,0);93 if(0 >sockfd)94 {95 perror("socket");96 return -1;97 }98

99 //准备地址

100 struct sockaddr_in addr ={AF_INET};101 addr.sin_port = htons(atoi(argv[1]));102 addr.sin_addr.s_addr = inet_addr(argv[2]);103

104 socklen_t addr_len = sizeof(addr);105

106

107

108 //绑定

109 int ret = bind(sockfd,(sockaddrp)&addr,addr_len);110 if(0 >ret)111 {112 perror("bind");113 return -1;114 }115

116

117 //设置最大排队数

118 listen(sockfd,50);119

120 int index = 0;121

122

123 while(count <= 50)124 {125 confd[count] = accept(sockfd,(sockaddrp)&src_addr[count],&src_len);126 ++count;127 //保存此次客户端地址所在下标方便后续传入

128 index = count-1;129

130 pthread_t tid;131 int ret = pthread_create(&tid,NULL,broadcast,&index);132 if(0 >ret)133 {134 perror("pthread_create");135 return -1;136 }137

138

139 }140

141

142 }

server.c

1 #include

2 #include

3 #include

4 #include

5 #include

6 #include

7 #include

8

9

10

11 typedef struct sockaddr *sockaddrp;12 intsockfd;13

14 void *recv_other(void *arg)15 {16 char buf[255]={};17 while(1)18 {19 int ret = recv(sockfd,buf,sizeof(buf),0);20 if(0 >ret)21 {22 perror("recv");23 return;24 }25 printf("%s\n",buf);26 }27 }28

29

30

31

32 int main(int argc,char **argv)33 {34 if(3 !=argc)35 {36 perror("参数错误");37 return -1;38 }39

40 //建立socket对象

41 sockfd = socket(AF_INET,SOCK_STREAM,0);42 if(0 >sockfd)43 {44 perror("socket");45 return -1;46 }47

48 //准备连接地址

49 struct sockaddr_in addr ={AF_INET};50 addr.sin_port = htons(atoi(argv[1]));51 addr.sin_addr.s_addr = inet_addr(argv[2]);52

53 socklen_t addr_len = sizeof(addr);54

55

56 //连接

57 int ret = connect(sockfd,(sockaddrp)&addr,addr_len);58 if(0 >ret)59 {60 perror("connect");61 return -1;62 }63

64 //发送名字

65 char buf[255] ={};66 char name[255] ={};67 printf("请输入您的昵称:");68 scanf("%s",name);69 ret = send(sockfd,name,strlen(name),0);70 if(0 >ret)71 {72 perror("connect");73 return -1;74 }75

76 //创建接收子线程

77 pthread_t tid;78 ret = pthread_create(&tid,NULL,recv_other,NULL);79

80 if(0 >ret)81 {82 perror("pthread_create");83 return -1;84 }85 //循环发送

86 while(1)87 {88 //printf("%s:",name);

89 scanf("%s",buf);90 int ret = send(sockfd,buf,strlen(buf),0);91 if(0 >ret)92 {93 perror("send");94 return -1;95 }96

97 //输入quit退出

98 if(0 == strcmp("quit",buf))99 {100 printf("%s,您已经退出了悟空聊天室\n",name);101 return 0;102 }103

104 }105

106 }

client.c

将两份代码分别编译生成相应可执行文件,例如在Linux下server,client,然后先执行./server 端口号 ip ,再执行./client 端口号 ip就可以运行这个聊天室了。

总结:关于网络编程,tcp是一种连接方式的通信方式,两边一旦建立连接,就可以通过send和recv函数发送消息,比较的可靠,缺点是速度比较慢(相对于udp来说)。另外关于多线程编程方面,线程其实是一个进程的实体,是一个进程的组成部分,多个线程共享除了栈区以外的大部分区域,因此进程间的通信比较方便,这种方便带来的代价是,当多个进程同时去操作同一量时,容易造成不可预知的错误,因此就引入了互斥量(锁)的概念,互斥量的使用就保证了进程间通信的同步。

原文:https://www.cnblogs.com/LyndonMario/p/9435684.html

c语言tcp多线程聊天,基于tcp和多线程的多人聊天室-C语言相关推荐

  1. java多人聊天室的实验任务_Java基于中介者模式实现多人聊天室功能示例

    本文实例讲述了Java基于中介者模式实现多人聊天室功能.分享给大家供大家参考,具体如下: 一 模式定义 中介者模式,用一个中介对象来封装一系列对象之间的交互,使各个对象中不需要显示地引用其他对象实例, ...

  2. nginx tcp代理_nginx 基于tcp/udp代理

    nginx从1.9.0版本开始,新增了ngx_stream_core_module模块,使nginx支持四层负载均衡.默认编译的时候该模块并未编译进去,需要编译的时候添加--with-stream,使 ...

  3. socket.io php 聊天室,WebSocket学习(一)——基于socket.io实现简单多人聊天室

    前言 什么是Websocket呢? 我们都知道在Http协议中,客户端与服务器端的通信是靠客户端发起请求,然后服务器端收到请求再进行回应,这个过程中,客户端是主动的,服务器端是被动的.Websocke ...

  4. 基于SpringBoot的websocket的多人聊天室项目

    文章目录 1.websocket 什么是websocket? 使用步骤 1.引入依赖 2.建立配置类 3.业务层 Web类 HTML 遇到的问题 项目github地址 1.websocket 什么是w ...

  5. linux线程池实现多线程并发,基于Linux的多线程池并发Web服务器设计-电子设计工程.PDF...

    基于Linux的多线程池并发Web服务器设计-电子设计工程.PDF 第 卷 第 期 电子设计工程 年 月 基于 的多线程池并发 服务器设计 陈 涛 任海兰 武汉邮电科学研究院 湖北 武汉 摘要 时至今 ...

  6. c语言小车倒车程序,基于单片机的汽车倒车系统设计(超声测距报警)(C语言程序)...

    基于单片机的汽车倒车系统设计(超声测距报警)(C语言程序)(任务书,毕业论文22000字) 摘要 本设计是以单片机技术为基础,实现对前方物体距离的测量.根据超声波指向性强,能量消耗慢,在介质中传播距离 ...

  7. html网页多人聊天,html5+js+.Net的即时多人聊天

    今天看了下websocket的知识,了解到这是html5新增的特性,主要用于实时web的通信.之前客户端获取服务端的数据,是通过客户端发出请求,服务端进行响应的模式,或者通过ajax每隔一段时间从后台 ...

  8. python实现多人聊天论文_python网络编程 双人多人聊天

    在学习网路编程时,我们首先要考虑的是其中的逻辑,我们借助打电话的形式来了解网络编程的过程, 我们打电话时属于呼叫方,接电话的属于被呼叫方,那么被呼叫方一直保持在待机状态,等待主呼叫方 呼叫,只有在被呼 ...

  9. 基于udp通信的在线多人聊天室

    1.项目要求 (1)用户可以登录聊天室. (2)在线用户可以接收到其他用户的上下线通知,和在线消息 (3)服务器可以发送系统消息 2.流程图 3.基本实现思路 (1)登陆操作,较为简陋,没有进行数据库 ...

最新文章

  1. 使用beanutil简化request值的接收
  2. Asp.net MVC 3实例学习之ExtShop(五)——产品详细页
  3. #define用法集锦[修正版]
  4. QT实现警报应用程序
  5. 单片机复位电路电容一定用电解电容_什么叫51单片机最小系统
  6. 第一章:初识lucene
  7. SyntaxError: invalid syntax-python报错
  8. 和情商高的人聊天是什么样的体验?
  9. php中reset()函数,php reset()函数 语法
  10. 土地利用转移矩阵_ArcGIS_土地利用转移矩阵(对比2010年-2020年土地利用变化)...
  11. Illustrator 教程,如何在 Illustrator 文档中缩放和平移?
  12. 网页素材精品:一组五彩缤纷的免费矢量背景素材
  13. qcom charger
  14. Aspen hysys换热器修改计算模式Find Fouling模式
  15. twitter最多关注者_Twitter的10个最具创意的用途
  16. wincc控件之FlexGrid系列(注册安装)
  17. msconfig设置windows启动项
  18. 智能制造:IntelligentSmart Manufacturing有何区别?
  19. linux虚拟机释放内存cache
  20. MySQL数据库的主从同步和读写分离

热门文章

  1. 30岁的程序员......
  2. java iqq_iQQ
  3. PHP爬虫,提取网站中的关键词,用一次正则匹配,然后再PHP数组的操作
  4. [附源码]SSM计算机毕业设计西柚网购物系统JAVA
  5. 解决C/C++报错error: cannot pass objects of non-trivially-copyable type ‘std::string’问题
  6. 云游戏的2022:破局、新生、元宇宙
  7. sprint 1 的总结
  8. java 版百度网盘功能
  9. JWT的学习和JJWT的使用
  10. 使用adb命令将手机和至电脑上的文件互传