ServerSocket.h
#ifndef __SERVERSOCKET_H__
#define
__SERVERSOCKET_H__

//
#define WIN32_LEAN_AND_MEAN
#include
<
windows.h
>

#include
"
SocketManage.h
"

#pragma
warning(disable:4786)
using
namespace
std;


#define
DEFAULT_PORT 6000
#define
LISTEN_NUM 20
#define
BUFFER_SIZE 32
#define
CLIENT_IP 50


/**/
/// class CServerSocket forward declaration
class
CServerSocket;


/**/
/// SInfo holds the data for thread parameter.
struct
tagSInfo

...
{
CServerSocket* pThis;
SOCKET ClientSocket;
char szMessage[BUFFER_SIZE];
char szClientIP[CLIENT_IP];
}
;

class
CServerSocket

...
{
public:
CServerSocket();
virtual ~CServerSocket();

/**//// Start Server
BOOL Start();

/**//// Stop Server
void Stop();

/**//// pure virtual function for future's inheritance.
virtual void OnMessage(LPSTR lpszIP, LPSTR lpszMessage) = 0;

/**//// Closing corresponding SOCKET's handle by its IP.
void CloseSocketByIP(LPCSTR lpszIP);

/**//// Send a message to client.
int SendMessageToClient(SOCKET hSocket, LPCSTR lpszMessage);
int SendMessageToClient(LPCSTR lpszIP, LPCSTR lpszMessage);

/**//// Send a message to all client.
void SendMessageToAllClient(LPCSTR lpszMessage);

/**//// Send a message to all client except for lpszIP
void SendMessageToAllClientExceptFor(LPCSTR lpszIP, LPCSTR lpszMessage);

/**//// recording SOCKET's status.
enum State

...{
SOCK_ERR,
SOCK_SUC
};

private:

/**//// Initialize SOCKET environment.
BOOL Initialization();

/**//// bind local with lPort
SOCKET Bind(USHORT lPort = DEFAULT_PORT);

/**//// accept a client's request and obtain its IP address by lpszIP.
SOCKET AcceptClient(SOCKET sListen, LPSTR lpszIP);

/**//// Worker Thraed that processing client's request.
static UINT __stdcall WorkThread(LPVOID pParam);
protected:
CSocketManage ClientManage;//! CSocketManage manages SOCKET and its IP address

private:
char szClientIP[50];
CRITICAL_SECTION cs;//! Critical_Section
}
;

#endif
#include
"
ServerSocket.h
"
#include
<
process.h
>
#include
<
stdio.h
>
//
#include <WINSOCK2.H>
#pragma
comment(lib, "WS2_32")


/**/
/// Constructor
CServerSocket::CServerSocket()

...
{

/**//// Initialize Critical Section
InitializeCriticalSection(&cs);
}


/**/
/// Destructor
CServerSocket::
~
CServerSocket()

...
{

/**//// Delete Critical Section
DeleteCriticalSection(&cs);

/**//// Cleanup
Stop();
}


/**/
/// Initialize SOCKET environment.
BOOL CServerSocket::Initialization()

...
{
WSADATA wsd;

/**//// Startup SOCKET library
if( WSAStartup(MAKEWORD(2, 2), &wsd) != 0) //! if failed, return FALSE

...{
return FALSE;
}

return TRUE;
}


/**/
/// Startup server
BOOL CServerSocket::Start()

...
{

/**//// Initialize environment.
if (Initialization() == FALSE)

...{
return FALSE;
}


/**//// bind
SOCKET sockListen;
if ((sockListen = Bind(DEFAULT_PORT)) == NULL)

...{
return FALSE;
}


/**//// listen to client's request
while (TRUE)

...{
SOCKET sockClient = NULL;
while(sockClient == NULL)

...{
sockClient = AcceptClient(sockListen, szClientIP);
}


/**//// Insert Client's SOCKET and its IP address to ClientManage.
ClientManage.AddIPToSocket(sockClient, szClientIP);


/**//// alloc a memory for struct SInfo in heap, release it in WorkThread()
struct tagSInfo *SOCKINFO = new struct tagSInfo;

SOCKINFO->pThis = this;
SOCKINFO->ClientSocket = sockClient;
strcpy(SOCKINFO->szClientIP, szClientIP);
memset(SOCKINFO->szMessage, 0, BUFFER_SIZE);


/**//// Startup a thread , use SOCKINFO as its parameter.
_beginthreadex(NULL, 0, WorkThread, (LPVOID)SOCKINFO, 0, NULL);
}

return TRUE;
}


/**/
/// Startup a thread , use the SOCKINFO as its parameter.
UINT CServerSocket::WorkThread(LPVOID pParam)

...
{
struct tagSInfo Param;

/**//// obtaining SOCKINFO
struct tagSInfo *lpParam = (struct tagSInfo*)pParam;

Param.ClientSocket = lpParam->ClientSocket;
Param.pThis = lpParam->pThis;
strcpy(Param.szClientIP, lpParam->szClientIP);
strcpy(Param.szMessage, lpParam->szMessage);

delete lpParam; //! release memory allocating in heap.
char recvbuf[BUFFER_SIZE];
State valState;


/**//// Receiving message from client and pass it to virtual function OnMessage()
while (TRUE)

...{
int nLeftToRecv = BUFFER_SIZE;
*recvbuf = 0;

/**//// do...while loop receives message until received it completely.
do

...{
char *pLeftBuf = (char *)( recvbuf + (BUFFER_SIZE - nLeftToRecv) );
int nRecvBytes = recv(Param.ClientSocket, pLeftBuf, nLeftToRecv, 0);
if(nRecvBytes == SOCKET_ERROR)

...{
valState = SOCK_ERR;
break;
}
nLeftToRecv -= nRecvBytes;
} while(nLeftToRecv > 0);

/**//// if has no errors in receiving progress, pass message to OnMessage().
if (valState != SOCK_ERR)

...{
Param.pThis->OnMessage(Param.szClientIP, recvbuf);
}
}

return 1;
}


/**/
/// bind local with lPort
SOCKET CServerSocket::Bind(USHORT lPort)

...
{

/**//// creating a socket in tcp/ip protocol.
SOCKET sServer = socket(AF_INET, SOCK_STREAM, 0);

/**//// initializing socket struct.
struct sockaddr_in servAddr;
servAddr.sin_family = AF_INET;
servAddr.sin_port = htons(lPort);
servAddr.sin_addr.s_addr = htonl(INADDR_ANY);


/**//// call socket api to bind
if(bind(sServer, (struct sockaddr *)&servAddr, sizeof(servAddr)) < 0)

...{
return NULL;
}

/**//// set SOCKET sServer to listening mode,and listen LISTEN_NUM at one time.
if(listen(sServer, LISTEN_NUM) != 0)

...{
return NULL;
}

return sServer;
}


/**/
/// accept a client's request and obtain its IP address by lpszIP.
SOCKET CServerSocket::AcceptClient(SOCKET sListen, LPSTR lpszIP)

...
{
struct sockaddr_in cliAddrTmp;

int cliAddrSize = sizeof(struct sockaddr_in);
SOCKET sClient = accept(sListen, (struct sockaddr *)&cliAddrTmp, &cliAddrSize);

if(sClient == INVALID_SOCKET)

...{
return NULL;
}

EnterCriticalSection(&cs);

sprintf(lpszIP, "%s", inet_ntoa(cliAddrTmp.sin_addr));

LeaveCriticalSection(&cs);
return sClient;
}


/**/
/// Stop Server
void
CServerSocket::Stop()

...
{
ClientManage.CloseAllSocket();
WSACleanup();
}


/**/
/// close a socket by ip address.
void
CServerSocket::CloseSocketByIP(LPCSTR lpszIP)

...
{
if (lpszIP == NULL)

...{
return;
}

SOCKET sSocket = ClientManage.GetSocketByIP(lpszIP);
if (sSocket != NULL)

...{
closesocket(sSocket);
ClientManage.DeleteIPSocket(lpszIP);
}
}


/**/
/// Send a message to client.
int
CServerSocket::SendMessageToClient(SOCKET hSocket, LPCSTR lpszMessage)

...
{
int iResult = send(hSocket, lpszMessage, BUFFER_SIZE, 0);

return iResult;
}


/**/
/// Send a message to client.
int
CServerSocket::SendMessageToClient(LPCSTR lpszIP, LPCSTR lpszMessage)

...
{
int iResult;

SOCKET hSocket = ClientManage.GetSocketByIP(lpszIP);

iResult = send(hSocket, lpszMessage, BUFFER_SIZE, 0);

return iResult;
}


/**/
/// Send a message to all client.
void
CServerSocket::SendMessageToAllClient(LPCSTR lpszMessage)

...
{
std::list<std::string> lstIP;
std::list<std::string>::iterator iter;

ClientManage.GetAllClientIP(lstIP);
for (iter = lstIP.begin(); iter != lstIP.end(); ++iter)

...{
string IP = *iter;
SOCKET hSocket = ClientManage.GetSocketByIP(IP.c_str());
send(hSocket, lpszMessage, strlen(lpszMessage), 0);
}
}


/**/
/// Send a message to all client except for lpszIP
void
CServerSocket::SendMessageToAllClientExceptFor(LPCSTR lpszIP, LPCSTR lpszMessage)

...
{
std::list<std::string> lstIP;
std::list<std::string>::iterator iter;
ClientManage.GetAllClientIP(lstIP);
for (iter = lstIP.begin(); iter != lstIP.end(); ++iter)

...{
string IP = *iter;

/**//// except for lpszIP
if (strcmp(IP.c_str(), lpszIP) == 0)

...{
continue;
}

SOCKET hSocket = ClientManage.GetSocketByIP(IP.c_str());
send(hSocket, lpszMessage, strlen(lpszMessage), 0);
}
}
#ifndef __SOCKETMANAGE_H__
#define
__SOCKETMANAGE_H__

#pragma
warning(disable:4786)
#pragma
warning(disable:4503)
#include
<
vector
>
#include
<
list
>
#include
<
map
>
#include
<
string
>
#include
<
algorithm
>

class
CSocketManage

...
{
public:

/**//// Constructor
CSocketManage();

/**//// Destructor
virtual ~CSocketManage();


/**//// return all client's IP address by list<>
void GetAllClientIP(std::list<std::string> & list);


/**//// return client's number
LONG GetSocketCount() const;


/**//// insert a client to CSocketManage
void AddIPToSocket(SOCKET hSocket, LPCSTR lpszIP);


/**//// remove a client from CSocketManage
void DeleteIPSocket(LPCSTR lpszIP);


/**//// get socket by ip address
SOCKET GetSocketByIP(LPCSTR lpszIP);


/**//// close all socket connection.
void CloseAllSocket();
private:
std::map< std::string, std::vector<std::string> > m_mapClientToMessage;

std::map< std::string,SOCKET > m_mapIPToSocket;
}
;

#endif
//
__SOCKETMANAGE_H__
#include
"
stdafx.h
"
#include
"
SocketManage.h
"
#include
<
assert.h
>

CSocketManage::CSocketManage()

...
{
m_mapIPToSocket.clear();
}

CSocketManage::
~
CSocketManage()

...
{

}

void
CSocketManage::GetAllClientIP(std::list
<
std::
string
>
&
listIP)

...
{

/**//// iterator's statement
std::map< std::string,SOCKET >::iterator iter;

for (iter = m_mapIPToSocket.begin();iter != m_mapIPToSocket.end();++iter)

...{
listIP.push_back(iter->first);
}
}

LONG CSocketManage::GetSocketCount()
const

...
{
return m_mapIPToSocket.size();
}

void
CSocketManage::AddIPToSocket(SOCKET hSocket, LPCSTR lpszIP)

...
{
m_mapIPToSocket.insert(std::make_pair(lpszIP, hSocket));
CString str;
str.Format("%d",m_mapIPToSocket.size());
AfxMessageBox(str);
}

void
CSocketManage::DeleteIPSocket(LPCSTR lpszIP)

...
{
std::map< std::string,SOCKET >::iterator iter;

for (iter = m_mapIPToSocket.begin();iter != m_mapIPToSocket.end();++iter)

...{

/**//// if found out target IP,then break
if(strcmp(iter->first.c_str(), lpszIP) == 0)

...{
break;
}
}


/**//// remove it from CSocketManage
m_mapIPToSocket.erase(iter);
}

SOCKET CSocketManage::GetSocketByIP(LPCSTR lpszIP)

...
{
if (lpszIP == NULL)

...{
return NULL;
}

std::map< std::string,SOCKET >::iterator iter;

for (iter = m_mapIPToSocket.begin();iter != m_mapIPToSocket.end();++iter)

...{
if(strcmp(iter->first.c_str(), lpszIP) == 0)

...{
break;
}
}

return iter->second;
}


/**/
/// close all client's socket.
void
CSocketManage::CloseAllSocket()

...
{
std::map< std::string,SOCKET >::iterator iter;
for (iter = m_mapIPToSocket.begin();iter != m_mapIPToSocket.end();++iter)

...{
closesocket(iter->second);
}
}































































































ServerSocket.cpp
































































































































































































































































































































SocketManage.h





















































SocketManage.cpp







































































































