多线程聊天程序设计linux,linux下socket多线程编程之多人聊天室

服务端

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define MAXLEN 1024

std::vector users; //保存用户组(已连接套接字)

void sendMsg(int fromfd, char* buff){

for(int v: users){ //转发给所有用户

if(v != fromfd)

if(send(v, buff, strlen(buff), 0) == -1){

std::cout << "发送失败:" << strerror(errno) << std::endl;

return;

}

}

}

void recvMsg(int fd){

char getbuff[MAXLEN] = {0};

char buff[MAXLEN] = {0};

while(1){

memset(getbuff, 0, MAXLEN);

memset(buff,0, MAXLEN);

if((recv(fd, getbuff, MAXLEN, 0)) == -1){

std::cout << "接收信息失败\n";

continue;

}

std::cout << "收到消息-->(" << getbuff << ")" << std::endl;

if(strcmp(getbuff, "bye") == 0){ //收到bye结束

break;

}

strcpy(buff, ">>>");

strcat(buff, getbuff);

sendMsg(fd, buff);

}

for(auto iter = users.begin(); iter != users.end(); ++iter){ //移除用户

if(*iter == fd){

users.erase(iter);

break;

}

}

close(fd); //关闭套接字

std::cout << "一位用户离开,当前连接数为:" << users.size() << std::endl;

}

int main(){

int listenfd, connfd;

struct sockaddr_in seraddr;

if((listenfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1){

std::cout << "creat socket error:" << strerror(errno) << std::endl;

exit(0);

}

memset(&seraddr, 0, sizeof(seraddr));

seraddr.sin_family = AF_INET;

seraddr.sin_port = htons(12345);

seraddr.sin_addr.s_addr = htonl(INADDR_ANY);

if(bind(listenfd, (struct sockaddr*)&seraddr, sizeof(seraddr)) == -1){ //绑定套接字

std::cout << "bind socket error:" << strerror(errno) << std::endl;

exit(0);

}

if(listen(listenfd, 10) == -1){ //监听

std::cout << "list error:" << strerror(errno) << std::endl;

exit(0);

}

std::cout << "服务已开启,等待用户接入...." << std::endl;

while(1){

if((connfd = accept(listenfd, (struct sockaddr*)NULL, NULL)) == -1){ //循环等待连接

std::cout << "connect error:" << strerror(errno) << std::endl;

exit(0);

}

users.push_back(connfd); //加入用户

std::cout << "一位用户进入聊天室,当前连接数为:" << users.size() << std::endl;

std::thread t(recvMsg, connfd); //创建线程处理该套接字的收发消息

t.detach(); //使线程非阻塞

}

close(connfd);

close(listenfd);

return 0;

}

客户端

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define MAXLEN 1024

char recvbuff[MAXLEN] = {0};

char sendbuff[MAXLEN] = {0};

char getbuff[1000] = {0};

void recvMsg(int fd){ //处理收到的消息

while(1){

memset(recvbuff, 0, MAXLEN);

recv(fd, recvbuff, MAXLEN, 0);

std::cout << recvbuff << std::endl;

}

}

int main(){

int clientfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

sockaddr_in serveraddr;

memset(&serveraddr, 0, sizeof(serveraddr));

serveraddr.sin_family = AF_INET;

serveraddr.sin_addr.s_addr = inet_addr("192.168.0.121");

serveraddr.sin_port = htons(12345);

char name[20] = {0};

std::cout << "请输入您的用户名:";

std::cin.getline(name, 20);

strcat(name, ":");

if((connect(clientfd, (sockaddr*)&serveraddr, sizeof(serveraddr)) == -1)){

perror("连接失败\n");

exit(0);

}

std::cout << "您已进入聊天室,祝您聊天愉快。" << std::endl;

std::thread t_(recvMsg, clientfd);

t_.detach();

while(1){

memset(getbuff, 0, 1004);

std::cin.getline(getbuff, MAXLEN);

if(strcmp(getbuff, "bye") == 0){

send(clientfd, getbuff, 1000, 0);

break;

}

memset(sendbuff, 0, MAXLEN);

strcpy(sendbuff, name);

strcat(sendbuff, getbuff);

if((send(clientfd, sendbuff, MAXLEN, 0) == -1)){

perror("发送失败\n");

exit(0);

}

}

close(clientfd);

}

编译参数添加 -std=c++11 -pthread

效果图

a843cc9175011d54cebf02fab2702e64.png

f6e25874c1b6c81b583100f1ba70354d.png

83e5043bc94cf22f6778ca08434dcf17.png

原文:https://www.cnblogs.com/Fire-In-Ice/p/14546490.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值