@@ -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
2725CIOCPSocket2::~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
19892void CIOCPSocket2::ReceivedData (int length)
@@ -220,7 +114,7 @@ void CIOCPSocket2::ReceivedData(int length)
220114
221115bool 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
323212void 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-
373238void CIOCPSocket2::Parsing (int length, char * pData)
374239{
375240}
376241
377242void CIOCPSocket2::Initialize ()
378243{
379- m_wPacketSerial = 0 ;
380244}
0 commit comments