I have built a simple c++ TCP server and client using winsock. The code all compiles without error however either the server is refusing connections or my client is failing to connect properly.
The code is alot to put onto stackoverflow so here is a pastebin for the server and Client.
https://pastebin.com/ZQavPxsR - Server Code
https://pastebin.com/cLFVp2B1 - Client Code
sockaddr_in clientService;
clientService.sin_family = AF_INET;
InetPton(AF_INET, _T("127.0.0.1"), &clientService.sin_addr.s_addr);
clientService.sin_port = htons(port);
if (connect(clientSocket, (SOCKADDR*)&clientService, sizeof(clientService)) == SOCKET_ERROR)
{
std::cout << "Client: connect() = Failed to connect." << std::endl;
WSACleanup();
system("pause");
return 0;
}
else
{
std::cout << "Client: connect() is OK." << std::endl;
std::cout << "Client: Can start sending and reciving data... " << std::endl;
}
Above is a snippet of the code that is from the client and is responsible for making the connection with the server.
acceptSocket = accept(serverSocket, NULL, NULL);
if (acceptSocket == INVALID_SOCKET)
{
std::cout << "Accept Failed: " << WSAGetLastError() << std::endl;
WSACleanup();
return -1;
}
else
{
std::cout << "Accepted connection " << std::endl;
system("pause");
WSACleanup();
}
Above is a snippet of the code that is from the server and is responsible for accepting the connection with the client.
Your server is not initializing the service.sin_port
field before calling bind()
, so the code exhibits undefined behavior. Your listening socket will end up trying to bind to whatever random port value was already present in the memory that the sin_port
field occupies. And if that value happens to be 0
, then bind()
will choose a random port from Windows' available ephemeral ports. In any case, it is very unlikely that your server is ever going to be listening on port 4679
, which is the port the client is trying to connect to.
On a side note, there are some other problems with your code:
In both client and server, your calls to InetPton()
should be passing in a pointer to the sockaddr_in::sin_addr
field, not the sockaddr_in::sin_addr.s_addr
field. It "works" only because s_addr
is the sole data member of sin_addr
and thus they have the same memory address. But technically, this is undefined behavior since InetPton()
wants an IN_ADDR*
not a ULONG*
.
Your server is not exiting if listen()
fails, is leaking serverSocket
whether accept()
succeeds or fails, and is leaking acceptSocket
if accept()
succeeds.
Your client is leaking clientSocket
whether connect()
succeeds or fails.