📄 chatserver.cpp
字号:
#include <winsock2.h>
#include <iostream.h>
#include <queue>
#include <list>
#include "ChatStruct.h"
#pragma comment(lib, "wsock32.lib")
HANDLE thread_commandHandle; //定义接收线程句柄
std::queue <MsgPair> msgQueue; //接收队列
std::list <UserOnline> userOnlineList; //在线用户队列
SOCKET sock; //socket
//服务器命令线程
void serverCommandThread();
//添加用户到列表
void addToOnlineQueue(sockaddr_in from,char *name);
//显示所有在线用户
void showOnlineQueue();
//用户退出聊天室
void logoutRoom(sockaddr_in &from);
//接收到聊天消息的处理函数
void recvMessage(sockaddr_in &from,GramHead* pHead,char *buf);
//发送消息
void sendMsg(char *data,char command);
//找出在线用户列表存放到pList中
void viewList(char *pList);
//将数据发送到指定地址
void sendListMsg(char *data,char command,sockaddr_in &from);
void main()
{
//1.启动SOCKET库,版本为2.0
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 0 );
err = WSAStartup(wVersionRequested, &wsaData );
if ( err != 0 )
{
cout<<"Socket2.0初始化失败,Exit!";
return;
}
if (LOBYTE(wsaData.wVersion)!= 2 || HIBYTE( wsaData.wVersion ) != 0 )
{
WSACleanup( );
return;
}
//2.创建socket,
sock = socket(
AF_INET, //internetwork: UDP, TCP, etc
SOCK_DGRAM, //SOCK_DGRAM说明是UDP类型
0 //protocol
);
if (sock == INVALID_SOCKET ) {
cout<<"Socket 创建失败,Exit!";
return;
}
//3.绑定
sockaddr_in myaddr; //sockaddr_in相当于sockaddr结构
memset(&myaddr,0,sizeof(myaddr));
myaddr.sin_family=AF_INET;
myaddr.sin_addr.s_addr = ADDR_ANY;
myaddr.sin_port=htons(5656);
bind(sock,(sockaddr*)&myaddr,sizeof(myaddr));
cout<<"服务器开启成功!"<<endl;
DWORD session_thread_id = 1;
thread_commandHandle=CreateThread(0,
0,
(LPTHREAD_START_ROUTINE)serverCommandThread,
0,
0,
&session_thread_id);
//接收到的SOCK地址
sockaddr_in from;
memset(&from,0,sizeof(from));
GramHead head,backHead;
int fromlength = sizeof(SOCKADDR),nnlen;
nnlen=fromlength;
char *buf=new char[1024];
memset(buf,0,1024);
long number=0;
while(1)
{
number++;
// 这里必须指定1024即分配的空间大小。如果使用str(buf)则无法计算,因为还未初始化
recvfrom(sock,buf,1024,0,(struct sockaddr FAR *)&from,(int FAR *)&fromlength);
memcpy(&head,buf,sizeof(GramHead));
switch(head.COMMAND)
{
case C_LOGIN: //登陆成功
backHead.COMMAND=S_LOGIN;
memcpy(buf,&backHead,sizeof(GramHead));
if( sendto(sock,buf,strlen(buf),0,(sockaddr*)&from,nnlen)
== SOCKET_ERROR )
cout<<WSAGetLastError()<<endl;
cout<<"用户"<<(unsigned char*)head.USERNO<<"登陆到聊天室!"<<endl;
addToOnlineQueue(from,head.USERNO); //添加加用户到在线列表
cout<<"聊天室当前人数为:"<<userOnlineList.size()<<endl;
// showOnlineQueue(); //显示用户
break;
case C_LOGOUT: //用户退出聊天室
logoutRoom(from);
break;
case C_MESSAGE: //用户聊天信息
char data[1024-sizeof(GramHead)];
memcpy(data,buf+sizeof(GramHead),1024-sizeof(GramHead));
recvMessage(from,&head,data);
break;
case C_USERLIST:
char plist[1024-sizeof(GramHead)];
memcpy(plist,buf+sizeof(GramHead),1024-sizeof(GramHead));
viewList(plist);
sendListMsg(plist,S_USERLIST,from);
break;
}
Sleep(500);
memset(buf,0,sizeof(buf));
}
delete buf;
if (!closesocket(sock))
{
WSAGetLastError();
return;
}
if (!WSACleanup())
{
WSAGetLastError();
return;
}
}
void addToOnlineQueue(sockaddr_in from,char *name)
{
sendMsg(name,S_USERLOGIN);
UserOnline online;
online.clientAddr=from;
strcpy(online.userName,name);
userOnlineList.push_back(online);
}
void showOnlineQueue()
{
int size=userOnlineList.size();
if (size==0)
{
cout<<"当前没有用户在线...."<<endl;
return;
}
else
{
cout<<"---------------------------------\n";
cout<<"当前在线人数为:"<<size<<endl;
}
std::list<UserOnline>::iterator theIterator;
for( theIterator = userOnlineList.begin(); theIterator != userOnlineList.end(); theIterator++ )
cout<<"IP地址:"<<inet_ntoa(theIterator->clientAddr.sin_addr)
<<" 端口号:"<<theIterator->clientAddr.sin_port<<" 用户名:"
<<theIterator->userName<<endl;
cout<<"---------------------------------\n";
}
void logoutRoom(sockaddr_in &from)
{
char msg[1024-sizeof(GramHead)];
std::list<UserOnline>::iterator theIterator;
for( theIterator = userOnlineList.begin(); theIterator != userOnlineList.end(); theIterator++ )
{
if (inet_ntoa(theIterator->clientAddr.sin_addr)==inet_ntoa(from.sin_addr)
&&theIterator->clientAddr.sin_port==from.sin_port)
{
memcpy(msg,theIterator->userName,sizeof(theIterator->userName));
cout<<msg<<"离开了聊天室......"<<endl;
userOnlineList.erase(theIterator);
sendMsg(msg,S_LOGOUT);
break;
}
}
cout<<"当前在线人数为:"<<userOnlineList.size()<<endl;
}
void recvMessage(sockaddr_in &from,GramHead* pHead,char *buf)
{
unsigned char dataBuf[1024];
GramHead head;
memcpy(head.USERNO,pHead->USERNO,sizeof(pHead->USERNO));
head.COMMAND=C_RECVMESSAGE;
memcpy(dataBuf,&head,sizeof(GramHead));
memcpy(dataBuf+sizeof(GramHead),buf,1024-sizeof(GramHead));
std::list<UserOnline>::iterator theIterator;
for( theIterator = userOnlineList.begin(); theIterator != userOnlineList.end(); theIterator++ )
{
if(sendto(sock,(const char *)dataBuf,1024,0,(sockaddr*)&theIterator->clientAddr,sizeof(SOCKADDR))
== SOCKET_ERROR )
cout<<WSAGetLastError()<<endl;
}
}
void sendMsg(char *data,char command)
{
char buf[1024];
memset(buf,0,1024);
GramHead head;
head.COMMAND=command;
memcpy(buf,&head,sizeof(GramHead));
memcpy(buf+sizeof(GramHead),data,strlen(data));
std::list<UserOnline>::iterator theIterator;
for( theIterator = userOnlineList.begin(); theIterator != userOnlineList.end(); theIterator++ )
{
if(sendto(sock,buf,1024,0,(sockaddr*)&theIterator->clientAddr,sizeof(SOCKADDR))
== SOCKET_ERROR )
cout<<WSAGetLastError()<<endl;
}
}
void sendListMsg(char *data,char command,sockaddr_in &from)
{
char buf[1024];
memset(buf,0,1024);
GramHead head;
head.COMMAND=command;
memcpy(buf,&head,sizeof(GramHead));
memcpy(buf+sizeof(GramHead),data,strlen(data));
if(sendto(sock,buf,1024,0,(sockaddr*)&from,sizeof(SOCKADDR))
== SOCKET_ERROR )
cout<<WSAGetLastError()<<endl;
}
//用户输入命令,完成操作
void serverCommandThread()
{
char ch[1024-sizeof(GramHead)];
while (1)
{
Sleep(1000);
memset(ch,0,1024);
cin>>ch;
if (!strcmp(ch,"list"))
{
showOnlineQueue();
}
else if(!strcmp(ch,"help"))
{
cout<<"---------------------------------\n";
cout<<"[list] 命令查看在线用户列表"<<endl;
cout<<"[send] 命令发送信息"<<endl;
cout<<"---------------------------------\n";
}
else if(ch[0]=='s'&&ch[1]=='e'&&ch[2]=='n'&&ch[3]=='d')
{
sendMsg(ch+4,S_MESSAGE);
}
}
}
void viewList(char *pList)
{
memset(pList,0,1024);
int start=0,length=0;
std::list<UserOnline>::iterator theIterator;
for( theIterator = userOnlineList.begin(); theIterator != userOnlineList.end(); theIterator++ )
{
length=strlen(theIterator->userName);
memcpy(pList+start,theIterator->userName,length);
pList[start+length]='\n';
start+=length+1;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -