-
Notifications
You must be signed in to change notification settings - Fork 14
/
ServerSocket.cpp
118 lines (100 loc) · 2.27 KB
/
ServerSocket.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include "ServerSocket.h"
#include <process.h>
#include <assert.h>
static unsigned int __stdcall ThreadProc(void *lpParameter)
{
((CServerSocket *)lpParameter)->Run();
return 0;
}
CServerSocket::CServerSocket()
{
m_nPort = 0;
m_bClosed = true;
m_pListener = NULL;
m_pSockets = NULL;
}
CServerSocket::~CServerSocket()
{
Close();
}
void CServerSocket::SetListener(ISocketListener *pListener)
{
m_pListener = pListener;
}
bool CServerSocket::Open(int nPort, int nMaxNum)
{
struct sockaddr_in localAddr;
int i;
unsigned int id;
Close();
m_nPort = nPort;
m_nMaxNum = nMaxNum; //max number of concurrent clients
m_ServerSocket = socket(AF_INET, SOCK_STREAM, 0);
if (m_ServerSocket == INVALID_SOCKET)
return false;
memset(&localAddr, 0, sizeof(localAddr));
localAddr.sin_family = AF_INET;
localAddr.sin_port = htons(m_nPort);
localAddr.sin_addr.s_addr = INADDR_ANY;
if (bind(m_ServerSocket, (struct sockaddr *)&localAddr, sizeof(localAddr)) == SOCKET_ERROR)
{
closesocket(m_ServerSocket);
return false;
}
if (listen(m_ServerSocket, m_nMaxNum) == SOCKET_ERROR)
{
closesocket(m_ServerSocket);
return false;
}
m_pSockets = new CSocket *[m_nMaxNum];
for (i = 0; i < m_nMaxNum; i++)
m_pSockets[i] = new CSocket(SOCK_STREAM);
m_bClosed = false;
m_hThread = (HANDLE)_beginthreadex(NULL, 0, ThreadProc, this, 0, &id); //begin thread
return true;
}
void CServerSocket::Close(void)
{
int i;
if (m_bClosed)
return;
m_bClosed = true;
closesocket(m_ServerSocket);
if (m_hThread != NULL)
{
WaitForSingleObject(m_hThread, INFINITE);
CloseHandle(m_hThread);
}
if (m_pSockets != NULL)
{
for (i = 0; i < m_nMaxNum; i++)
delete m_pSockets[i];
delete[] m_pSockets;
m_pSockets = NULL;
}
}
int CServerSocket::GetPort(void)
{
return m_nPort;
}
void CServerSocket::Run(void)
{
int i, nSize;
struct sockaddr_in remoteAddr;
SOCKET socket;
nSize = sizeof(remoteAddr);
while (!m_bClosed)
{
socket = accept(m_ServerSocket, (struct sockaddr *)&remoteAddr, &nSize); //accept connection
if (socket != INVALID_SOCKET)
{
for (i = 0; i < m_nMaxNum; i++)
if (!m_pSockets[i]->Active()) //find an inactive CSocket
{
m_pSockets[i]->Open(socket, m_pListener, &remoteAddr); //receive input data
break;
}
assert(i < m_nMaxNum);
}
}
}