服务端
#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
效果图
原文:https://www.cnblogs.com/Fire-In-Ice/p/14546490.html