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.
CodePudding user response:
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 thesockaddr_in::sin_addr
field, not thesockaddr_in::sin_addr.s_addr
field. It "works" only becauses_addr
is the sole data member ofsin_addr
and thus they have the same memory address. But technically, this is undefined behavior sinceInetPton()
wants anIN_ADDR*
not aULONG*
.Your server is not exiting if
listen()
fails, is leakingserverSocket
whetheraccept()
succeeds or fails, and is leakingacceptSocket
ifaccept()
succeeds.Your client is leaking
clientSocket
whetherconnect()
succeeds or fails.