c++ - Winsock invalid received byte number -
i'm facing winsock
related problem when trying validate number of received bytes.
in application i'm using non-blocking socket in order throw own timeout
exception. here according code initialization of winsock
:
// initialize winsock wsadata winsockdata; word dllversion = makeword(2, 1); long iresult = wsastartup(dllversion, &winsockdata); if (iresult != no_error) return; addrinfo* serveraddress = nullptr; addrinfo* ptr = nullptr, hints; zeromemory(&hints, sizeof(hints)); hints.ai_family = af_inet; hints.ai_socktype = sock_stream; hints.ai_protocol = ipproto_tcp; iresult = getaddrinfo("127.0.0.1", "10011", &hints, &serveraddress); if (iresult != 0) return; // create communication socket socket connectsocket = socket(af_inet, sock_stream, /*ipproto_tcp*/0); if (connectsocket == invalid_socket) return; // establish connection server iresult = connect(connectsocket, serveraddress->ai_addr, (int)serveraddress->ai_addrlen); if (iresult == socket_error) return; // set socket non-blocking ulong mode = 1; m_iresult = ioctlsocket(m_connectsocket, fionbio, &mode); if (m_iresult == socket_error) return; // server address info not needed anymore freeaddrinfo(serveraddress);
the application connects given telnet server first, sends request , awaits according response message.
the incoming data gets stored in appropriate char array, called m_servermsg
(with fixed size of bufsize
, set @ 4200 bytes).
if retrieving server response message taking long (max. allowed time stored in g_requesttimeout
), own timeoutexception
gets thrown.
given server message has reached end if newline charachter (\r\n
) has been found in message buffer.
however, following part retrieving server response message not working expected. expected incoming data bytes 1,040
, actual bytes 3,435,973,836
.
unsigned long long starttime = getwalltimeinms(); bool retry = true; unsigned int receivedbytes = 0; // fetch server response { try { m_iresult = fetchmessage(m_connectsocket, m_servermsg, int(bufsize - receivedbytes)); if (m_iresult == socket_error) throw std::exception(); if (m_iresult > 0) { (unsigned int = receivedbytes; < receivedbytes + m_iresult; i++) { char* eol = strstr(m_servermsg, "\r\n"); if (eol) { retry = false; break; } } receivedbytes += m_iresult; } } catch (commexception e) { // in case there's short delay in retrieving server response message if (getwalltimeinms() - starttime < g_requesttimeout) sleep(20); else // response timeout exceeded; connection has been lost throw commexception("server not responding in time.", commproblem::connectionlost); } catch (std::exception& e) { std::cout << "there socket related problem." << std::endl; std::cout << "error code: " << wsagetlasterror() << std::endl; } } while (retry);
and how function fetchmessage()
looks like:
int commcenter::fetchmessage(socket socket, char* buffer, int bufsize, int flags) { int result = recv(socket, buffer, bufsize, flags); // if operation couldn't executed (e.g. because server down), // throw according exception if (result == socket_error) { if (wsagetlasterror() == wsaewouldblock) throw commexception("delay in connection.", commproblem::delay); else throw; } return result; }
this part
for (unsigned int = receivedbytes; < receivedbytes + m_iresult; i++) { if (m_servermsg[i] == '\r\n') { retry = false; break; } }
is not correct, '\r\n'
not same "\r\n"
, can not compare this.
to correct use strstr
function this
char* eol = strstr(m_servermsg, "\r\n"); if(eol != null) { retry = false; break; }
or convert m_servermsg
std::string
, use find
method
if(std::string(m_servermsg, receivedbytes, m_iresult).find("\r\n") != std::string::npos) { retry = false; break; }
Comments
Post a Comment