基于tcp和多线程的多人聊天室-C语言

时间:2022-03-20 23:55:46

之前在学习关于网络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 &lpar;31&rpar; - 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 &lpar;30&rpar; - Communication(通信)之基于 Socket TCP 开发一个多人聊天室

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

  5. java 通过TCP&bsol;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. Ubuntu12&period;04下编译OpenCv2&period;4&period;9程序

    引用地址http://blog.163.com/huai_jing@126/blog/static/171861983201311103411229/ 方法1:直接命令编译: g++ main.cpp ...

  2. Fiddler 过滤 css&comma;图片等请求url 正则表达式

    设置步骤: 1.勾选 Request Headers 中的 Hide if url contains 过滤项 2.贴入下方正则表达式 REGEX:(?insx)/[^?/]*.(css|ico|jpg ...

  3. &lbrack;JLOI2015&rsqb;管道连接

    题目描述 小铭铭最近进入了某情报部门,该部门正在被如何建立安全的通道连接困扰.该部门有 n 个情报站,用 1 到 n 的整数编号.给出 m 对情报站 ui;vi 和费用 wi,表示情报站 ui 和 v ...

  4. 559&period; Maximum Depth of N-ary Tree

    https://leetcode.com/problems/maximum-depth-of-n-ary-tree/description/ 非常简单的题目,连edge case 都没有.思路就是:最 ...

  5. IIS日志分析工具-Log Parser

    下载地址:https://www.microsoft.com/en-us/download/details.aspx?id=24659 参考链接: https://www.cnblogs.com/fu ...

  6. org&period;springframework&period;beans&period;factory&period;CannotLoadBeanClassException-估计mapper出参 和 po字段不对应了

    DEBUG [localhost-startStop-1] - Ignoring bean class loading failure for bean 'itemsService'org.sprin ...

  7. Tomcat通过自带的Cluster方式实现Session会话共享环境操作记录

    一般来说,在多个tomcat集群业务中,session会话共享是必须的需求,不然前端nginx转发过来的请求不知道之前请求在哪台tomcat节点上,从而就找不到session以至于最终导致请求失败.要 ...

  8. 深入理解java虚拟机---虚拟机工具jconsole&lpar;十八&rpar;

    Jconsole,Java Monitoring and Management Console. Jconsole是JDK自带的监控工具,在JDK/bin目录下可以找到.它用于连接正在运行的本地或者远 ...

  9. mysql-学习笔记1

    1.while循环的一个方便的用法是循环处理一个SQL查询结果中的数据行. 2.mysqli_fetch_array(),这个内置的PHP函数从一个数据库查询的结果中获取一个数据行,可以搭配while ...

  10. LSTM 文本情感分析&sol;序列分类 Keras

    LSTM 文本情感分析/序列分类 Keras 请参考 http://spaces.ac.cn/archives/3414/   neg.xls是这样的 pos.xls是这样的neg=pd.read_e ...