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

具体的实现过程:

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

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

话不多说,直接上代码

 #include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <pthread.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h> typedef struct sockaddr *sockaddrp; //存储客户端地址的结构体数组
struct sockaddr_in src_addr[];
socklen_t src_len = sizeof(src_addr[]); //连接后记录confd数组
int confd[] = {}; //设置连接人数
int count = ; void *broadcast(void *indexp)
{
int index = *(int *)indexp;
char buf_rcv[] = {};
char buf_snd[] = {};
//第一次读取用户姓名
char name[] = {};
int ret = recv(confd[index],name,sizeof(name),);
if( > ret)
{
perror("recv");
close(confd[index]);
return;
} while()
{
bzero(buf_rcv,sizeof(buf_rcv));
recv(confd[index],buf_rcv,sizeof(buf_rcv),); //判断是否退出
if( == strcmp("quit",buf_rcv))
{
sprintf(buf_snd,"%s已经退出悟空聊天室",name);
for(int i = ;i <= count;i++)
{
if(i == index || == confd[i])
{
continue;
} send(confd[i],buf_snd,strlen(buf_snd),);
}
confd[index] = -;
pthread_exit(); } sprintf(buf_snd,"%s:%s",name,buf_rcv);
printf("%s\n",buf_snd);
for(int i = ;i <= count;i++)
{
if(i == index || == confd[i])
{
continue;
} send(confd[i],buf_snd,sizeof(buf_snd),);
} } } int main(int argc,char **argv)
{
printf("悟空聊天室服务器端开始运行\n"); //创建通信对象
int sockfd = socket(AF_INET,SOCK_STREAM,);
if( > sockfd)
{
perror("socket");
return -;
} //准备地址
struct sockaddr_in addr = {AF_INET};
addr.sin_port = htons(atoi(argv[]));
addr.sin_addr.s_addr = inet_addr(argv[]); socklen_t addr_len = sizeof(addr); //绑定
int ret = bind(sockfd,(sockaddrp)&addr,addr_len);
if( > ret)
{
perror("bind");
return -;
} //设置最大排队数
listen(sockfd,); int index = ; while(count <= )
{
confd[count] = accept(sockfd,(sockaddrp)&src_addr[count],&src_len);
++count;
//保存此次客户端地址所在下标方便后续传入
index = count-; pthread_t tid;
int ret = pthread_create(&tid,NULL,broadcast,&index);
if( > ret)
{
perror("pthread_create");
return -;
} } }

server.c

 #include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <pthread.h>
#include <string.h> typedef struct sockaddr *sockaddrp;
int sockfd; void *recv_other(void *arg)
{
char buf[]= {};
while()
{
int ret = recv(sockfd,buf,sizeof(buf),);
if( > ret)
{
perror("recv");
return;
}
printf("%s\n",buf);
}
} int main(int argc,char **argv)
{
if( != argc)
{
perror("参数错误");
return -;
} //建立socket对象
sockfd = socket(AF_INET,SOCK_STREAM,);
if( > sockfd)
{
perror("socket");
return -;
} //准备连接地址
struct sockaddr_in addr = {AF_INET};
addr.sin_port = htons(atoi(argv[]));
addr.sin_addr.s_addr = inet_addr(argv[]); socklen_t addr_len = sizeof(addr); //连接
int ret = connect(sockfd,(sockaddrp)&addr,addr_len);
if( > ret)
{
perror("connect");
return -;
} //发送名字
char buf[] = {};
char name[] = {};
printf("请输入您的昵称:");
scanf("%s",name);
ret = send(sockfd,name,strlen(name),);
if( > ret)
{
perror("connect");
return -;
} //创建接收子线程
pthread_t tid;
ret = pthread_create(&tid,NULL,recv_other,NULL); if( > ret)
{
perror("pthread_create");
return -;
}
//循环发送
while()
{
//printf("%s:",name);
scanf("%s",buf);
int ret = send(sockfd,buf,strlen(buf),);
if( > ret)
{
perror("send");
return -;
} //输入quit退出
if( == strcmp("quit",buf))
{
printf("%s,您已经退出了悟空聊天室\n",name);
return ;
} } }

client.c

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

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

基于tcp和多线程的多人聊天室-C语言的更多相关文章

  1. 与众不同 windows phone (31) - Communication(通信)之基于 Socket UDP 开发一个多人聊天室

    原文:与众不同 windows phone (31) - Communication(通信)之基于 Socket UDP 开发一个多人聊天室 [索引页][源码下载] 与众不同 windows phon ...

  2. 66 网络编程(五)——TCP多线程实现多人聊天室

    思路 客户端读写各一个类,可以使内部类,实现Runnable.读写类都与服务器端建立连接,一个收,一个发. 客户端实现接收和转发.多线程实现每个客户端的连接(使与各客户端的连接独立). 服务器端中创建 ...

  3. Python编写基于socket的非阻塞多人聊天室程序(单线程&多线程)

    前置知识:socket非阻塞函数(socket.setblocking(False)),简单多线程编程 代码示例: 1. 单线程非阻塞版本: 服务端: #!/usr/bin/env python # ...

  4. 与众不同 windows phone (30) - Communication(通信)之基于 Socket TCP 开发一个多人聊天室

    原文:与众不同 windows phone (30) - Communication(通信)之基于 Socket TCP 开发一个多人聊天室 [索引页][源码下载] 与众不同 windows phon ...

  5. java 通过TCP\UDP 协议实现多人聊天,点对点,文件传送-----分服务器端和客户端

    java 通过TCP\UDP 协议实现多人聊天,点对点,文件传送-----分服务器端和客户端 启动界面如下图: 首先启动服务器: 客户端登陆,登陆成功后为: 默认发送是全部用户,是多人发送. 当在边列 ...

  6. 多人聊天室(Java)

    第1部分 TCP和UDP TCP:是一种可靠地传输协议,是把消息按一个个小包传递并确认消息接收成功和正确才发送下一个包,速度相对于UDP慢,但是信息准确安全:常用于一般不要求速度和需要准确发送消息的场 ...

  7. Apache MiNa 实现多人聊天室

    Apache MiNa 实现多人聊天室 开发环境: System:Windows JavaSDK:1.6 IDE:eclipse.MyEclipse 6.6 开发依赖库: Jdk1.4+.mina-c ...

  8. Python实现网络多人聊天室

    网络多人聊天室 文件结构: chatroom ├── client.py  # 客户端代码 ├── language.py  # 语言文件 ├── server.py  # 服务端代码 └── set ...

  9. Python实现网络多人聊天室 - Windows

    项目名称:多人聊天室项目结构: client.py server.py settings.py项目思路:服务端接收客户端连接,客户端发送信息给服务端,服务端将信息发送给所有客户端.项目实现:主进程负责 ...

随机推荐

  1. Bing词典分析

    0x01 Bug测试结果 本次测试的是Bing词典wp版本V4.5.2,经过测试,共发现如下Bug. 1.更新后,旧版本首页的每日单词与文章推荐不能重新获得,部分搜索历史记录丢失. 2.在单词挑战模式 ...

  2. sho

    手工编程:hello world 全部用命令行工具和Notepad编辑器,用手工创建并编译一个C的命令行程序:hello world. public class Hello{         publ ...

  3. PAT 1033 旧键盘打字

    https://pintia.cn/problem-sets/994805260223102976/problems/994805288530460672 旧键盘上坏了几个键,于是在敲一段文字的时候, ...

  4. 转《ionic生命周期》

    1.认识ionic的生命周期钩子 截至ionic 3.8.0版本,框架提供了8个钩子函数,它们分别会在页面生命周期的各个阶段被触发,我们来简单了解一下. 1.1 ionViewDidLoad 页面加载 ...

  5. hive 远程管理

  6. [转] python 模块学习 hashlib

    转自: http://www.cnblogs.com/BeginMan/p/3328172.html 一.hashlib概述 涉及加密服务:14. Cryptographic Services 其中 ...

  7. 使用nmon进行系统监控

      一.下载并安装: 下载地址:http://nmon.sourceforge.net/pmwiki.php?n=Site.Download 下载版本:nmon16g_x86.tar.gz 不用的Li ...

  8. 退役前的记录(2018.10.14-NOIP2018)

    退役前的记录 诸位好,我是\(CJ\)最菜的\(Oier\),已经是\(G2\)的老年选手了,不知道什么时候就会退役了,总之\(G1\ double\)的机会已经没有了,去年因为联赛失利而止步,而今年 ...

  9. 浅谈教你如何掌握Linux系统

    linux能做什么?相信绝大数人都有这样的疑问.可以玩吃鸡吗?可以玩lol吗? 如果你是以娱乐的名义来评价linux的可用性,对不起,linux可能不适合你,因为linux是一个工具,他是教你聪明的, ...

  10. MT【225】两平行直线夹曲线

    已知函数$f(x)=x^3-3ax,(x\in(0,1))$若关于$x$的不等式$|f(x)|\le \dfrac{1}{4}$恒成立,求实数$a=$____ 方法一:代数法,转化成恒成立问题,略.方 ...