I have a Server and a Client Application, both on the same System.
The client connects to the system via a TCP-Socket, which works fine.
The Server has a loop in which it keeps accepting clients on a non-blocking listen socket.
The function body for the accepting loop:
std::unique_ptr<Connection> p_conn(nullptr);
bool connection_establish_pending = false;
while(!StopCondition_)
{
if(!connection_establish_pending)
p_conn.reset(new Connection);
// accept new connection
auto stat = p_conn->Accept(ListenSocket_);
if(stat == Connection::Error)
break; // listen socket is unusable
if(stat == Connection::Wouldblock)
{
connection_establish_pending = true;
std::this_thread::sleep_for(std::chrono::milliseconds(300));
continue;
}
// connection has been established
connection_establish_pending = false;
// create client handling thread
std::thread t(_connection_handler_thread, p_conn.release(), this);
this->ThreadList_.push_back(std::move(t)); // add to list
}
`Connection` is a simple wrapper around a socket.
After the connection was accepted a new thread is started to handle communications with the client:
void ConnectionHandler(std::unique_ptr<Connection> pConn)
{
Message msg;
std::vector<char> buf;
try
{
// main loop
while(pConn->Recv(msg)) // receive a message
{
switch(msg.RequestCode())
{
case 1:
{
// prepare answer msg...
pConn->Send(msg);
}
break;
case 2:
// ...
}
} // while(recv)
}
catch(...)
{
}
}
At the moment, the client is nothing more than the following:
std::string ip = "localhost", port = "12345";
// Connect to server
cout << "Establishing connection..." << endl;;
Server.Connect(ip, port);
cout << "Connection established to: " << ip << ":" << port << endl;
/* Send a message to host*/
const char Data[] = "Counter"; const size_t data_size = strlen(Data);
cout << "Sending Message \"" << Data << "\"" << endl;
auto ret = Server.SendRequest(1, Data, data_size);
if(!ret)
cout << "Connection closed serverside" << endl;
else
{
if(!Server.RecvAnswer(rq, vecData))
cout << "Connection closed serverside" << endl;
else
{
cout << "Answer:\n\tCode = " << rq << "\n\tData:" << std::string(vecData.data(), vecData.size()) << endl;
}
// Now try to get the module info for "Counter"
cout << "Requesting module info now... " << endl;
ret = Server.SendRequest(2, Data, data_size);
if(!ret)
cout << "Connection closed serverside" << endl;
else
{
if(!Server.RecvAnswer(rq, vecData))
cout << "Connection closed serverside";
else
cout << "Answer:\n\tCode = " << rq << "\n\tData:" << std::string(vecData.data(), vecData.size()) << endl;
}
}
Following are my wrappers for receiving and sending data via a socket:
//prepare a buffer to be used in calls to 'recv'
std::unique_ptr<char[]> pBuf(new char[BytesToRecv]);
int Ret = 0;
size_t BytesReceived = 0;
do
{
//clear the buffer
memset(pBuf.get(), '\0', BytesToRecv);
Ret = recv(Get(), pBuf.get(), BytesToRecv - BytesReceived, 0);
if(Ret == 0) // Graceful shutdown
return Status::Closed;
if (Ret == SOCKET_ERROR)
{
auto ret_code = GetErrorStatus(); // Wouldblock, Disconnected/Unreachable, Aborted
if(ret_code == Status::Error)
throw(socket_exception(Get(), "Failed to recv"));
return ret_code;
}
//Append to the Data-Buffer
//Data.append(inc::StringToWString(std::string(pBuf.get(), Ret)));
memcpy_s(&pData[BytesReceived], BytesToRecv - BytesReceived, pBuf.get(), Ret);
//Count bytes received
BytesReceived += static_cast<size_t>(Ret);
//reset the return code
Ret = 0;
} while (BytesReceived < BytesToRecv);
And here my sending code:
size_t total = 0; //total sent
size_t bytesleft = DataSize; //bytes left to be sent
int ret = 0;
//as long as there is data to send...
while (total < DataSize)
{
//...send what's left
ret = send(Get(), pData + total, bytesleft, 0);
if(ret == SOCKET_ERROR)
{
auto ret = GetErrorStatus(); // Aborted, Wouldblock, Unreachable/Disconnected
if(ret == Status::Error)
throw(socket_exception(Get(), "Failed to send"));
return ret;
}
total += ret;
bytesleft -= ret;
}
And here is the code to RecvAnswer: (it makes a call to the recv-code above and extracts the data to a buffer (nothin really network related except from the call to the recv)
bool RecvAnswer(request_type& Request, std::vector<char>& vecData)
{
Message Msg;
if(!pimpl->Connection_.Recv(Msg))
return false;
vecData = Msg.Data();
Request = Msg.RequestCode();
return true;
}
The problem that occurs is, that when i run the client without breakpoints, step-through, etc it successfully sends the first request and receives data from the server. After the second request when i call recv it returns the 10053-Error.
Funnily, when i step through the code i get the 10053-error right on the first call to recv.
Turning off firewall and antivirus software does not help.
Strange thing to me is, that it workswhen i put the listening(!) socket into blocking mode.
Any help would be greatly appreciated.
Thank You!
If required, i could also add someone to my visualstudio.com-project (if she/he as an visualstudio-account) so the full code could be read.