Skip to content

Commit 7caee1a

Browse files
committed
VersionManager: Migrate to basic asio implementation
1 parent 212bffc commit 7caee1a

9 files changed

Lines changed: 319 additions & 563 deletions

File tree

Server/VersionManager/Define.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,6 @@ constexpr int DB_PROCESS_TIMEOUT = 100;
3131
#define STATE_CONNECTED 0X01
3232
#define STATE_DISCONNECTED 0X02
3333
#define STATE_GAMESTART 0x03
34-
35-
// Overlapped flag
36-
#define OVL_RECEIVE 0X01
37-
#define OVL_SEND 0X02
38-
#define OVL_CLOSE 0X03
3934
////////////////////////////////////////////////////////////
4035

4136
typedef union

Server/VersionManager/IOCPSocket2.cpp

Lines changed: 62 additions & 198 deletions
Original file line numberDiff line numberDiff line change
@@ -16,183 +16,77 @@ static char THIS_FILE[] = __FILE__;
1616
// Construction/Destruction
1717
//////////////////////////////////////////////////////////////////////
1818

19-
CIOCPSocket2::CIOCPSocket2()
19+
CIOCPSocket2::CIOCPSocket2(CIOCPort* iocPort)
20+
: m_pIOCPort(iocPort), m_Socket(iocPort->GetIoContext())
2021
{
2122
m_pBuffer = new CCircularBuffer(SOCKET_BUFF_SIZE);
22-
m_Socket = INVALID_SOCKET;
23-
24-
m_pIOCPort = nullptr;
2523
}
2624

2725
CIOCPSocket2::~CIOCPSocket2()
2826
{
2927
delete m_pBuffer;
3028
}
3129

32-
bool CIOCPSocket2::Create(UINT nSocketPort, int nSocketType, long lEvent, const char* lpszSocketAddress)
33-
{
34-
int ret;
35-
36-
m_Socket = socket(AF_INET, nSocketType/*SOCK_STREAM*/, 0);
37-
if (m_Socket == INVALID_SOCKET)
38-
{
39-
ret = WSAGetLastError();
40-
// see https://learn.microsoft.com/en-us/windows/win32/winsock/windows-sockets-error-codes-2
41-
spdlog::error("IOCPSocket2::Create: Winsock error {}", ret);
42-
return false;
43-
}
44-
45-
m_hSockEvent = WSACreateEvent();
46-
if (m_hSockEvent == WSA_INVALID_EVENT)
47-
{
48-
ret = WSAGetLastError();
49-
spdlog::error("IOCPSocket2::Create: CreateEvent winsock error {}", ret);
50-
return false;
51-
}
52-
53-
return true;
54-
}
55-
56-
int CIOCPSocket2::Send(char* pBuf, long length, int dwFlag)
30+
int CIOCPSocket2::Send(char* pBuf, long length)
5731
{
58-
int ret_value = 0;
59-
WSABUF out;
60-
DWORD sent = 0;
61-
OVERLAPPED* pOvl;
62-
HANDLE hComport = nullptr;
63-
6432
if (length > MAX_PACKET_SIZE)
6533
return 0;
6634

67-
char pTBuf[MAX_PACKET_SIZE] = {};
35+
constexpr int PacketHeaderSize = 6;
36+
37+
// TODO: A circular buffer would be better for this.
38+
auto sendBuffer_ = std::make_unique<uint8_t[]>(length + PacketHeaderSize);
39+
uint8_t* sendBuffer = sendBuffer_.get();
40+
6841
int index = 0;
6942

70-
pTBuf[index++] = (uint8_t) PACKET_START1;
71-
pTBuf[index++] = (uint8_t) PACKET_START2;
72-
memcpy(pTBuf + index, &length, 2);
43+
sendBuffer[index++] = PACKET_START1;
44+
sendBuffer[index++] = PACKET_START2;
45+
memcpy(&sendBuffer[index], &length, 2);
7346
index += 2;
74-
memcpy(pTBuf + index, pBuf, length);
47+
memcpy(&sendBuffer[index], pBuf, length);
7548
index += length;
76-
pTBuf[index++] = (uint8_t) PACKET_END1;
77-
pTBuf[index++] = (uint8_t) PACKET_END2;
78-
79-
out.buf = pTBuf;
80-
out.len = index;
81-
82-
pOvl = &m_SendOverlapped;
83-
pOvl->Offset = OVL_SEND;
84-
pOvl->OffsetHigh = out.len;
49+
sendBuffer[index++] = (uint8_t) PACKET_END1;
50+
sendBuffer[index++] = (uint8_t) PACKET_END2;
8551

86-
ret_value = WSASend(m_Socket, &out, 1, &sent, dwFlag, pOvl, nullptr);
87-
88-
if (ret_value == SOCKET_ERROR)
52+
try
8953
{
90-
int last_err;
91-
last_err = WSAGetLastError();
92-
93-
if (last_err == WSA_IO_PENDING)
94-
{
95-
spdlog::debug("IOCPSocket2::Send: socketId={} IO_PENDING", m_Sid);
96-
m_nPending++;
97-
if (m_nPending > 3)
98-
goto close_routine;
99-
sent = length;
100-
}
101-
else if (last_err == WSAEWOULDBLOCK)
102-
{
103-
spdlog::debug("IOCPSocket2::Send: socketId={} WOULDBLOCK", m_Sid);
104-
105-
m_nWouldblock++;
106-
if (m_nWouldblock > 3)
107-
goto close_routine;
108-
return 0;
109-
}
110-
else
111-
{
112-
spdlog::error("IOCPSocket2::Send: socketId={} winsock error={}",
113-
m_Sid, last_err);
114-
m_nSocketErr++;
115-
goto close_routine;
116-
}
54+
m_Socket.async_write_some(asio::buffer(sendBuffer, index),
55+
[this, sendBuffer_ = std::move(sendBuffer_)]
56+
(const asio::error_code& ec, size_t bytesTransferred) mutable
57+
{
58+
m_pIOCPort->OnPostSend(ec, bytesTransferred, this);
59+
});
11760
}
118-
else if (ret_value == 0)
61+
catch (const asio::system_error& ex)
11962
{
120-
m_nPending = 0;
121-
m_nWouldblock = 0;
122-
m_nSocketErr = 0;
63+
spdlog::error("IOCPSocket2::Send: failed to post send for socketId={}: {}",
64+
m_Sid, ex.what());
65+
Close();
66+
return -1;
12367
}
12468

125-
return sent;
126-
127-
close_routine:
128-
pOvl = &m_RecvOverlapped;
129-
pOvl->Offset = OVL_CLOSE;
130-
131-
hComport = m_pIOCPort->m_hServerIOCPort;
132-
PostQueuedCompletionStatus(hComport, 0, m_Sid, pOvl);
133-
134-
return -1;
69+
return index;
13570
}
13671

137-
int CIOCPSocket2::Receive()
72+
void CIOCPSocket2::Receive()
13873
{
139-
int RetValue;
140-
WSABUF in;
141-
DWORD insize, dwFlag = 0;
142-
OVERLAPPED* pOvl;
143-
HANDLE hComport = nullptr;
74+
if (m_pIOCPort == nullptr)
75+
return;
14476

14577
memset(m_pRecvBuff, 0, sizeof(m_pRecvBuff));
146-
in.len = MAX_PACKET_SIZE;
147-
in.buf = m_pRecvBuff;
148-
149-
pOvl = &m_RecvOverlapped;
150-
pOvl->Offset = OVL_RECEIVE;
15178

152-
RetValue = WSARecv(m_Socket, &in, 1, &insize, &dwFlag, pOvl, nullptr);
153-
154-
if (RetValue == SOCKET_ERROR)
79+
try
15580
{
156-
int last_err = WSAGetLastError();
157-
if (last_err == WSA_IO_PENDING)
158-
{
159-
// TRACE("RECV : IO_PENDING[SID=%d]\n", m_Sid);
160-
// m_nPending++;
161-
// if (m_nPending > 3)
162-
// goto close_routine;
163-
return 0;
164-
}
165-
else if (last_err == WSAEWOULDBLOCK)
166-
{
167-
spdlog::debug("IOCPSocket2::Receive: socketId={} WOULDBLOCK", m_Sid);
168-
169-
m_nWouldblock++;
170-
if (m_nWouldblock > 3)
171-
goto close_routine;
172-
return 0;
173-
}
174-
else
175-
{
176-
spdlog::error("IOCPSocket2::Receive: socketId={} winsock error={}",
177-
m_Sid, last_err);
178-
179-
m_nSocketErr++;
180-
if (m_nSocketErr == 2)
181-
goto close_routine;
182-
return -1;
183-
}
81+
m_Socket.async_read_some(asio::buffer(m_pRecvBuff),
82+
std::bind(&CIOCPort::OnPostReceive, m_pIOCPort, std::placeholders::_1, std::placeholders::_2, this));
83+
}
84+
catch (const asio::system_error& ex)
85+
{
86+
spdlog::error("IOCPSocket2::Receive: failed to post receive for socketId={}: {}",
87+
m_Sid, ex.what());
88+
Close();
18489
}
185-
186-
return (int) insize;
187-
188-
close_routine:
189-
pOvl = &m_RecvOverlapped;
190-
pOvl->Offset = OVL_CLOSE;
191-
192-
hComport = m_pIOCPort->m_hServerIOCPort;
193-
PostQueuedCompletionStatus(hComport, 0, m_Sid, pOvl);
194-
195-
return -1;
19690
}
19791

19892
void CIOCPSocket2::ReceivedData(int length)
@@ -220,7 +114,7 @@ void CIOCPSocket2::ReceivedData(int length)
220114

221115
bool CIOCPSocket2::PullOutCore(char*& data, int& length)
222116
{
223-
uint8_t* pTmp;
117+
uint8_t* pTmp;
224118
int len;
225119
bool foundCore;
226120
MYSHORT slen;
@@ -247,7 +141,6 @@ bool CIOCPSocket2::PullOutCore(char*& data, int& length)
247141
if (pTmp[i] == PACKET_START1
248142
&& pTmp[i + 1] == PACKET_START2)
249143
{
250-
// if( m_wPacketSerial >= wSerial ) goto cancelRoutine;
251144
sPos = i + 2;
252145

253146
slen.b[0] = pTmp[sPos];
@@ -304,77 +197,48 @@ void CIOCPSocket2::Close()
304197
if (m_pIOCPort == nullptr)
305198
return;
306199

307-
HANDLE hComport = nullptr;
308-
OVERLAPPED* pOvl;
309-
pOvl = &m_RecvOverlapped;
310-
pOvl->Offset = OVL_CLOSE;
311-
312-
hComport = m_pIOCPort->m_hServerIOCPort;
313-
314-
int retValue = PostQueuedCompletionStatus(hComport, 0, m_Sid, pOvl);
315-
if (retValue == 0)
200+
asio::error_code ec;
201+
try
202+
{
203+
asio::post(m_pIOCPort->GetIoContext(), std::bind(&CIOCPort::OnPostClose, m_pIOCPort, this));
204+
}
205+
catch (const asio::system_error& ex)
316206
{
317-
int errValue = GetLastError();
318-
spdlog::error("IOCPSocket2::Close: socketId={} PostQueuedCompletionStatus error={}",
319-
m_Sid, errValue);
207+
spdlog::error("IOCPSocket2::Close: failed to post close for socketId={}: {}",
208+
m_Sid, ex.what());
320209
}
321210
}
322211

323212
void CIOCPSocket2::CloseProcess()
324213
{
325214
m_State = STATE_DISCONNECTED;
326215

327-
if (m_Socket != INVALID_SOCKET)
328-
closesocket(m_Socket);
216+
if (m_Socket.is_open())
217+
{
218+
asio::error_code ec;
219+
m_Socket.close(ec);
220+
221+
if (ec)
222+
{
223+
spdlog::error("IOCPSocket2::CloseProcess: close() failed for socketId={}: {}",
224+
m_Sid, ec.message());
225+
}
226+
}
329227
}
330228

331-
void CIOCPSocket2::InitSocket(CIOCPort* pIOCPort)
229+
void CIOCPSocket2::InitSocket(asio::ip::tcp::socket&& socket)
332230
{
333-
m_pIOCPort = pIOCPort;
334-
m_RecvOverlapped.hEvent = nullptr;
335-
m_SendOverlapped.hEvent = nullptr;
231+
m_Socket = std::move(socket);
336232
m_pBuffer->SetEmpty();
337233
m_nSocketErr = 0;
338-
m_nPending = 0;
339-
m_nWouldblock = 0;
340234

341235
Initialize();
342236
}
343237

344-
bool CIOCPSocket2::Accept(SOCKET listensocket, sockaddr* addr, int* len)
345-
{
346-
m_Socket = accept(listensocket, addr, len);
347-
if (m_Socket == INVALID_SOCKET)
348-
{
349-
int err = WSAGetLastError();
350-
spdlog::error("IOCPSocket2::Accept: socketId={} winsock error={}",
351-
m_Sid, err);
352-
return false;
353-
}
354-
355-
// int flag = 1;
356-
// setsockopt(m_Socket, SOL_SOCKET, SO_DONTLINGER, (char *)&flag, sizeof(flag));
357-
358-
// int lensize, socklen=0;
359-
360-
// getsockopt( m_Socket, SOL_SOCKET, SO_RCVBUF, (char*)&socklen, &lensize);
361-
// TRACE("getsockopt : %d\n", socklen);
362-
363-
// linger lingerOpt;
364-
365-
// lingerOpt.l_onoff = 1;
366-
// lingerOpt.l_linger = 0;
367-
368-
// setsockopt(m_Socket, SOL_SOCKET, SO_LINGER, (char *)&lingerOpt, sizeof(lingerOpt));
369-
370-
return true;
371-
}
372-
373238
void CIOCPSocket2::Parsing(int length, char* pData)
374239
{
375240
}
376241

377242
void CIOCPSocket2::Initialize()
378243
{
379-
m_wPacketSerial = 0;
380244
}

0 commit comments

Comments
 (0)