📄 serversocket.cpp
字号:
#include "StdAfx.h"
#include "ServerSocket.h"
#include <stdio.h>
#include "ToClientSocket.h"
#include "..\thread\Lock.h"
#include "..\thread\LockSection.h"
#include "..\error\FaultCenter.h"
using namespace fs::error;
LockSection section;
namespace fs
{
namespace socket
{
ServerSocket::ServerSocket( UINT port,UINT backlog/*=5*/ )
:Socket(port)
{
int retval=bind(m_socket,m_address.GetPtr(),m_address.GetSize());
FaultCenter::TryCatch(_T("socket"),_T("bind"),retval);
retval=listen(m_socket,backlog);
FaultCenter::TryCatch(_T("socket"),_T("listen"),retval);
printf("server is listening...\n\n");
}
ServerSocket::~ServerSocket(void)
{
Lock lock(§ion);
SocketIterator it;
for ( it = toClientSocketMap.begin();
it != toClientSocketMap.end(); it++ )
{
delete it->second;
}
}
VOID ServerSocket::Run()
{
while (isRun)
{
printf("waiting for connect...\n\n");
ToClientSocket* pToClientSocket=AcceptD();
if (!pToClientSocket)
{
break;
}
OnAccept(pToClientSocket);
}
Stop();
printf("server exits from listening\n");
}
VOID ServerSocket::OnAccept( ToClientSocket* pToClientSocket )
{
pToClientSocket->Start();
Lock lock(§ion);
toClientSocketMap.insert(SocketPair( pToClientSocket->GetThreadId(), pToClientSocket ));
User user;
user.id=pToClientSocket->GetThreadId();
userMap.insert(UserPair(pToClientSocket->GetThreadId(),user));
}
VOID ServerSocket::SendMessageToClients(CONST CHAR* pBuf,UINT size)
{
Lock lock(§ion);
SocketIterator it;
for ( it = toClientSocketMap.begin( );
it != toClientSocketMap.end( ); it++ )
{
Send(it->second,pBuf,size);
}
}
VOID ServerSocket::SendMessageToClients( CONST CString& chatContent )
{
Message msg;
msg.SetCode(4);
msg.AddData(chatContent);
SendMessageToClients(msg.GetBuffer(),msg.GetSize());
}
ToClientSocket* ServerSocket::AcceptD( )
{
//addr接收客户端地址信息
Address clientAddr;
INT len = clientAddr.GetSize();
SOCKET toClientSocket
= accept( m_socket,clientAddr.GetPtr(),&len);
if(!FaultCenter::TryCatch(_T("socket"),_T("accept"),toClientSocket))
{
return NULL;
}
//每收到一个请求,创建一个ToClientSocket用于与客户端通信
ToClientSocket* pToClientSocket=new ToClientSocket(this);
pToClientSocket->SetSocket(toClientSocket);
pToClientSocket->SetAddress(clientAddr);
printf("receive a connect from %s\n",clientAddr.GetIp());
return pToClientSocket;
}
VOID ServerSocket::OnReceive( ToClientSocket* pToClientSocket,CHAR* pBuf,UINT size )
{
CHAR* pTempBuf=pBuf;
Message msg;
msg.SetBuffer(pTempBuf,size);
SHORT code=msg.GetCode();
switch(code)
{
case MESSAGE_CODE_AUTHENTIATE://认证
{
CString userName;
msg.NextData(userName);
CString password;
msg.NextData(password);
userMap[pToClientSocket->GetThreadId()].SetUserName(userName);
userMap[pToClientSocket->GetThreadId()].SetPassword(password);
Address addr=pToClientSocket->GetAddress();
userMap[pToClientSocket->GetThreadId()].SetIpAddress(addr.GetIp());
if (User::Authenticate(userMap[pToClientSocket->GetThreadId()]))
{
OnClientAuthentiateSuccess(pToClientSocket);
}
else
{
OnClientAuthentiateFail(pToClientSocket);
}
break;
}
case MESSAGE_CODE_CHAT://收到聊天内容
{
OnClientChat(pToClientSocket,pBuf,size);
break;
}
case 100://绘线
{
OnClientDraw(pToClientSocket,pBuf,size);
break;
}
}
//在父类中会delete[] pBuf
Socket::OnReceive(pBuf,size);
}
VOID ServerSocket::OnClientExit(ToClientSocket* pToClientSocket)
{
printf("client exits.\n");
{
Lock lock(§ion);
//key应该为pToClientSocket->m_address.GetIp()
toClientSocketMap.erase(pToClientSocket->GetThreadId());
userMap.erase(pToClientSocket->GetThreadId());
SendOnlineUsersToClients();
}
delete pToClientSocket;
}
VOID ServerSocket::OnPassiveDisconnect()
{
}
VOID ServerSocket::SendOnlineUsersToClients( )
{
Message msg;
msg.SetCode(MESSAGE_CODE_USERS);
UserIterator it;
for (it = userMap.begin();
it != userMap.end();it++)
{
msg.AddData(it->second);
}
SocketIterator it2;
for (it2 = toClientSocketMap.begin();
it2 != toClientSocketMap.end();it2++)
{
if (userMap[it2->first].IsLogin())
{
Send(it2->second, msg.GetBuffer(),msg.GetSize() );
}
}
}
VOID ServerSocket::OnClientAuthentiateSuccess( ToClientSocket* pToClientSocket )
{
Message msg;
//通知客户认证成功
msg.SetCode(MESSAGE_CODE_AUTHENTIATE_SUCCESS);
Send(pToClientSocket,msg.GetBuffer(),msg.GetSize());
}
VOID ServerSocket::OnClientAuthentiateFail( ToClientSocket* pToClientSocket )
{
Message msg;
//通知客户认证失败
msg.SetCode(MESSAGE_CODE_AUTHENTIATE_FAIL);
Send(pToClientSocket,msg.GetBuffer(),msg.GetSize());
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -