C++如何实现聊天小程序(C++,移动开发)

时间:2024-05-06 04:56:01 作者 : 石家庄SEO 分类 : 移动开发
  • TAG :

涉及的技术:

  • c++网络编程

  • c++多线程

  • c++ STL

设计原理

以一个结构体的形式存储客户端,用vector存取存在的客户端,开启多线程处理逻辑

服务器允许登陆多个客户端,允许公屏聊天也允许私聊,默认情况下属于公屏聊天,若想私聊,格式为“@用户名+要发送的消息”;运行效果如下图:

C++如何实现聊天小程序

服务器实现

#include"stdafx.h"#include<iostream>#include"windows.h"//一定要包含该头文件#include"process.h"#include<string>#include<vector>#include<algorithm>usingnamespacestd;#pragmacomment(lib,"WS2_32.lib")//显示加载ws2_32.dllws2_32.dll就是最新socket版本intg_curPlayerNum=0;//当前连接数constchar*g_PlayerName[]=//假定的聊天者名字{"aaaa","bbbb","cccc","dddd",};structPlayerInfo//利用结构存储连接的客户端{SOCKETsock;stringname;};vector<PlayerInfo>g_clientSockList;//利用vector存取已连接的客户端voidprocess(void*param){intindex=*(int*)param;//当前子线程编号while(1){//服务器接收信息//intindex=*(int*)param;charbuf[2048]={0};//接收缓冲区intbytes;if((bytes=recv(g_clientSockList[index].sock,buf,sizeof(buf),0))==SOCKET_ERROR){cout<<"服务器接收数据失败!"<<endl;}//服务器转发(含逻辑处理)if(buf[0]=="@"){//私聊stringBuf(buf);stringrecvPlayerName=Buf.substr(1,4);//分离出接收者名字copy(g_clientSockList[index].name.begin(),g_clientSockList[index].name.end(),&buf[1]);for(vector<PlayerInfo>::iteratorit=g_clientSockList.begin();it!=g_clientSockList.end();it++){if(it->name==recvPlayerName){if(send(it->sock,buf,strlen(buf),0)==SOCKET_ERROR){cout<<"发送数据失败to"<<it->name<<endl;}break;}}}else//群聊cout<<g_clientSockList[index].name<<"对"<<"所有人说:"<<buf<<endl;}}intmain(){cout<<"-----------聊天室服务器-----------"<<endl;//套接字初始化WSADATAwsaData;//这个结构被用来存储被WSAStartup函数调用后返回的WindowsSockets数据。WORDsockVersion=MAKEWORD(2,2);//windows网络编程库的版本号信息if(WSAStartup(sockVersion,&wsaData)!=0)//WSAStartup函数是在程序中初始化并加载Windows网络{cout<<"套接字初始化失败!"<<endl;return0;}//创建服务器套接字SOCKETSeverSocket;if((SeverSocket=socket(AF_INET,SOCK_STREAM,0))==SOCKET_ERROR){cout<<"套接字创建失败!"<<endl;return0;}structsockaddr_inSeverAddress;//一个绑定地址:有IP地址,有端口号,有协议族memset(&SeverAddress,0,sizeof(sockaddr_in));//初始化结构体SeverAddress.sin_family=AF_INET;SeverAddress.sin_addr.S_un.S_addr=htonl(INADDR_ANY);//填入本机IP地址SeverAddress.sin_port=htons(60000);//设定端口号//绑定套接字指定绑定的IP地址和端口号if(bind(SeverSocket,(sockaddr*)&SeverAddress,sizeof(SeverAddress))==SOCKET_ERROR){cout<<"套接字绑定失败!"<<endl;return0;}//服务器监听if(listen(SeverSocket,SOMAXCONN)==SOCKET_ERROR)//监听的第二个参数就是:能存放多少个客户端请求,到并发编程的时候很有用{cout<<"监听失败!"<<endl;return0;}elsecout<<"服务器等待连接......"<<endl;while(1){//服务器接受连接请求sockaddr_inrevClientAddress;//套接字的地址,端口SOCKETrevClientSocket=INVALID_SOCKET;//用来接收客户端连接//memset(&revClientAddress,0,sizeof(revClientAddress));intaddlen=sizeof(revClientAddress);if((revClientSocket=accept(SeverSocket,(sockaddr*)&revClientAddress,&addlen))==INVALID_SOCKET){cout<<"接受客户端连接失败!"<<endl;return0;}PlayerInfostPlayerInfo;stPlayerInfo.sock=revClientSocket;stPlayerInfo.name=g_PlayerName[g_curPlayerNum];g_clientSockList.push_back(stPlayerInfo);inttemp=g_curPlayerNum;_beginthread(process,0,&temp);//创建子线程来收发数据g_curPlayerNum++;cout<<stPlayerInfo.name<<"上线啦!"<<endl;}return0;}

客户端

#include"stdafx.h"#include"windows.h"#include"iostream"#include"process.h"#include<string>usingnamespacestd;#pragmacomment(lib,"ws2_32.lib")voidReceive(void*param){stringmsg;while(1){//客户端接受来自服务器的数据SOCKETclientSocket=*(SOCKET*)(param);charrecvbuf[2048]={};//接收缓冲区if(recv(clientSocket,recvbuf,2048,0)==SOCKET_ERROR){cout<<"数据接受失败"<<endl;}else{msg=recvbuf;charsendPlayerName[5]={0};intlen=strlen(recvbuf);//消息长度copy(&recvbuf[1],&recvbuf[5],sendPlayerName);//分离出名字msg=msg.substr(5,len-5);cout<<sendPlayerName<<"对你说:"<<msg<<endl;}}}voidSend(void*param){while(1){//客户端发送数据给服务器SOCKETclientSocket=*(SOCKET*)(param);charsendbuf[2048]={};//发送缓冲区cin.getline(sendbuf,2048);if(send(clientSocket,sendbuf,strlen(sendbuf),0)==SOCKET_ERROR){cout<<"发送消息失败!";}elsecout<<"发送消息成功"<<endl;}}intmain(){cout<<"-----------个人客户端-----------"<<endl;WSADATAwsa;if(WSAStartup(MAKEWORD(2,2),&wsa)!=0){cout<<"套接字初始化失败!"<<endl;}SOCKETclientSocket;if((clientSocket=socket(AF_INET,SOCK_STREAM,0))==SOCKET_ERROR){cout<<"套接字创建失败!"<<endl;}Sleep(30);structsockaddr_inClientAddress;//一个绑定地址:有IP地址,有端口号,有协议族memset(&ClientAddress,0,sizeof(sockaddr_in));//初始化结构体ClientAddress.sin_family=AF_INET;ClientAddress.sin_addr.S_un.S_addr=htonl(INADDR_ANY);//填入本机IP地址//ClientAddress.sin_port=htons(60001);//设定端口号//绑定套接字指定绑定的IP地址和端口号if(bind(clientSocket,(sockaddr*)&ClientAddress,sizeof(ClientAddress))==SOCKET_ERROR){cout<<"套接字绑定失败!"<<endl;return0;}structsockaddr_inSeverAddress;//服务器地址也就是即将要连接的目标地址memset(&SeverAddress,0,sizeof(sockaddr_in));SeverAddress.sin_family=AF_INET;SeverAddress.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");//127.0.0.1表示本机ip地址SeverAddress.sin_port=htons(60000);//设定端口号//开始连接if(connect(clientSocket,(sockaddr*)&SeverAddress,sizeof(SeverAddress))==SOCKET_ERROR){cout<<"客户端:和服务器连接失败!"<<endl;return0;}elsecout<<"与服务器连接成功!"<<endl;//创建两个子线程_beginthread(Receive,0,&clientSocket);_beginthread(Send,0,&clientSocket);Sleep(INFINITE);//这里采用另外一种技术避免主线程执行完退出――使其无限期休眠//关闭socketif(clientSocket!=INVALID_SOCKET){closesocket(clientSocket);clientSocket=INVALID_SOCKET;}return0;}
 </div> <div class="zixun-tj-product adv-bottom"></div> </div> </div> <div class="prve-next-news">
本文:C++如何实现聊天小程序的详细内容,希望对您有所帮助,信息来源于网络。
上一篇:C++ SOCKET多线程怎么实现聊天小程序下一篇:

24 人围观 / 0 条评论 ↓快速评论↓

(必须)

(必须,保密)

阿狸1 阿狸2 阿狸3 阿狸4 阿狸5 阿狸6 阿狸7 阿狸8 阿狸9 阿狸10 阿狸11 阿狸12 阿狸13 阿狸14 阿狸15 阿狸16 阿狸17 阿狸18