⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 serversocket.cpp

📁 一个HTTP协议的封装类
💻 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(&section);
			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(&section);

			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(&section);
			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(&section);
				//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 + -