Commit 46c53602 by Carwyn

Fixes: 1.由于完成例程中未等待重叠操作完成导致 accept 崩溃问题; 2. 协议消息体结构优化

parent 4f17833d
...@@ -96,13 +96,8 @@ BOOL FMSockServer::_Listen() ...@@ -96,13 +96,8 @@ BOOL FMSockServer::_Listen()
sockaddr_in addr_client = { 0 }; sockaddr_in addr_client = { 0 };
int addr_len = sizeof(addr_client); int addr_len = sizeof(addr_client);
SOCKET sclient = INVALID_SOCKET; SOCKET sclient = INVALID_SOCKET;
try { sclient = accept(_socket, (sockaddr*)&addr_client, &addr_len);
sclient = accept(_socket, (sockaddr*)&addr_client, &addr_len);
}
catch (...) {
FMLOG("Accept exception");
}
if (INVALID_SOCKET != sclient) { if (INVALID_SOCKET != sclient) {
DWORD str_addr_len = 32; DWORD str_addr_len = 32;
TCHAR str_addr[32] = { 0 }; TCHAR str_addr[32] = { 0 };
...@@ -113,11 +108,11 @@ BOOL FMSockServer::_Listen() ...@@ -113,11 +108,11 @@ BOOL FMSockServer::_Listen()
LPFMSOCKDATA io_data = NULL; LPFMSOCKDATA io_data = NULL;
io_data = (LPFMSOCKDATA)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(FMSOCKDATA)); io_data = (LPFMSOCKDATA)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(FMSOCKDATA));
//! Receive length first //! Receive length first
io_data->buffer[0].len = sizeof(io_data->header); io_data->buffer.len = sizeof(io_data->header);
io_data->buffer[0].buf = (char*)&io_data->header; io_data->buffer.buf = (char*)&io_data->header;
io_data->relay = _relay; io_data->relay = _relay;
io_data->socket = sclient; io_data->socket = sclient;
WSARecv(sclient, io_data->buffer, 1, NULL, &io_data->flags, &io_data->overlap, FMSockServer::RecvRoutine); WSARecv(sclient, &io_data->buffer, 1, NULL, &io_data->flags, &io_data->overlap, FMSockServer::RecvRoutine);
DWORD res = SleepEx(1000, TRUE); DWORD res = SleepEx(1000, TRUE);
while (res != WAIT_IO_COMPLETION) { while (res != WAIT_IO_COMPLETION) {
...@@ -139,7 +134,6 @@ BOOL FMSockServer::_Listen() ...@@ -139,7 +134,6 @@ BOOL FMSockServer::_Listen()
} }
} }
FMLOG(_T("Stopped listening.")); FMLOG(_T("Stopped listening."));
return TRUE; return TRUE;
...@@ -148,10 +142,16 @@ BOOL FMSockServer::_Listen() ...@@ -148,10 +142,16 @@ BOOL FMSockServer::_Listen()
void FMSockServer::RecvRoutine(DWORD err, DWORD bytes, LPWSAOVERLAPPED overlapped, DWORD flags) void FMSockServer::RecvRoutine(DWORD err, DWORD bytes, LPWSAOVERLAPPED overlapped, DWORD flags)
{ {
FMLOG(_T("Received bytes: %ld."), bytes);
LPFMSOCKDATA io_data = (LPFMSOCKDATA)overlapped; LPFMSOCKDATA io_data = (LPFMSOCKDATA)overlapped;
if (bytes <= 0) {
closesocket(io_data->socket);
HeapFree(GetProcessHeap(), 0, io_data);
return;
}
FMLOG(_T("Received bytes: %ld."), bytes);
if (io_data->header.flag == FMSOCKFLAG) { if (io_data->header.flag == FMSOCKFLAG) {
if (err != 0 || bytes == 0) { if (err != 0 || bytes == 0) {
//! Connection was closed by client //! Connection was closed by client
...@@ -161,17 +161,25 @@ void FMSockServer::RecvRoutine(DWORD err, DWORD bytes, LPWSAOVERLAPPED overlappe ...@@ -161,17 +161,25 @@ void FMSockServer::RecvRoutine(DWORD err, DWORD bytes, LPWSAOVERLAPPED overlappe
else if (strlen(io_data->msg) < io_data->header.len) { else if (strlen(io_data->msg) < io_data->header.len) {
//! Receive data //! Receive data
LPFMSOCKDATA io_new_data = NULL; LPFMSOCKDATA io_new_data = NULL;
io_new_data = (LPFMSOCKDATA)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(FMSOCKDATA) + io_data->header.len); UINT len = sizeof(FMSOCKDATA) + io_data->header.len;
io_new_data->header = io_data->header; io_new_data = (LPFMSOCKDATA)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
io_new_data->buffer[0] = io_data->buffer[0];
io_new_data->buffer[0].buf = (char*)&io_new_data->header; io_new_data->buffer = io_data->buffer;
io_new_data->buffer[1].len = io_data->header.len; io_new_data->buffer.len = io_data->header.len;
io_new_data->buffer[1].buf = io_new_data->msg; io_new_data->buffer.buf = io_new_data->msg;
io_new_data->socket = io_data->socket; io_new_data->socket = io_data->socket;
io_new_data->relay = io_data->relay; io_new_data->relay = io_data->relay;
io_new_data->flags = io_data->flags; io_new_data->flags = io_data->flags;
WSARecv(io_new_data->socket, &io_new_data->buffer[1], 1, NULL, &io_new_data->flags, &io_new_data->overlap, FMSockServer::RecvRoutine); io_new_data->header = io_data->header;
WSARecv(io_new_data->socket, &io_new_data->buffer, 1, NULL, &io_new_data->flags, &io_new_data->overlap, FMSockServer::RecvRoutine);
DWORD res = SleepEx(1000, TRUE);
while (res != WAIT_IO_COMPLETION) {
FMLOG(_T("Rewaiting for I/O completion..."));
res = SleepEx(1000, TRUE);
}
} }
else { else {
//! Legal freemud api data //! Legal freemud api data
...@@ -184,11 +192,23 @@ void FMSockServer::RecvRoutine(DWORD err, DWORD bytes, LPWSAOVERLAPPED overlappe ...@@ -184,11 +192,23 @@ void FMSockServer::RecvRoutine(DWORD err, DWORD bytes, LPWSAOVERLAPPED overlappe
if (response) { if (response) {
send(io_data->socket, response, len, 0); send(io_data->socket, response, len, 0);
LPFMSOCKDATA io_new_data = NULL;
io_new_data = (LPFMSOCKDATA)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(FMSOCKDATA));
//! Receive length first
io_new_data->buffer.len = sizeof(io_new_data->header);
io_new_data->buffer.buf = (char*)&io_new_data->header;
io_new_data->relay = io_data->relay;
io_new_data->socket = io_data->socket;
WSARecv(io_new_data->socket, &io_new_data->buffer, 1, NULL, &io_new_data->flags, &io_new_data->overlap, FMSockServer::RecvRoutine);
DWORD res = SleepEx(1000, TRUE);
while (res != WAIT_IO_COMPLETION) {
FMLOG(_T("Rewaiting for I/O completion..."));
res = SleepEx(1000, TRUE);
}
} }
else { else {
FMLOG(_T("Failed to determine response data.")); FMLOG(_T("Failed to determine response data."));
} }
closesocket(io_data->socket);
} }
} }
else { else {
......
...@@ -30,15 +30,13 @@ typedef struct { ...@@ -30,15 +30,13 @@ typedef struct {
typedef struct typedef struct
{ {
WSAOVERLAPPED overlap; //! WSAOVERLAPPED object must be the first member WSAOVERLAPPED overlap; //! WSAOVERLAPPED object must be the first member
WSABUF buffer[2]; //! buffer[0] holds length WSABUF buffer;
//! buffer[1] holds contents
DWORD flags; DWORD flags;
SOCKET socket; SOCKET socket;
FMApiRelay *relay; FMApiRelay *relay;
FMSOCKHEADER header; FMSOCKHEADER header;
char msg[1]; char msg[1];
}FMSOCKDATA, *LPFMSOCKDATA; }FMSOCKDATA, *LPFMSOCKDATA;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment