Search code examples
c++socketsvisual-studio-2017windows-10winsock

TCP Server Socket Opening Fail in C++


I am currently creating a program where I require a TCP server for communication with an android application. I have written and tested the TCP server as an individual project and it runs completely fine. When including this into a larger project, where I have other processes, it no longer opens the socket for listening.

My project is being created in Visual Studio 2017 and the libraries I am using are:

  • WS2_32.lib for the TCP
  • OpenCV for image processing
  • Libcurl for sending files to a database
  • ACTi SDK for pulling image feed from a camera

The TCP server code I have written is (taken from https://www.youtube.com/watch?v=WDn-htpBlnU&t=162s):

void TCPServer()
{
    //Initalize winsock
    WSADATA wsData;
    WORD ver = MAKEWORD(2, 2);

    int wsOk = WSAStartup(ver, &wsData);
    if (wsOk != 0)
    {
        cerr << "Can't init winsock" << endl;
        return;
    }

    //Create a socket
    SOCKET listening = socket(AF_INET, SOCK_STREAM, 0);
    if (listening == INVALID_SOCKET)
    {
        cerr << "Can't create socket" << endl;
        return;
    }

    //Bind the socket to an ip address and port
    sockaddr_in hint;
    hint.sin_family = AF_INET;
    hint.sin_port = htons(100);
    hint.sin_addr.S_un.S_addr = INADDR_ANY; //Could use inet_pton()

    bind(listening, (sockaddr*)&hint, sizeof(hint));

    //Tell Winsock the socket is for listening 
    listen(listening, SOMAXCONN);

    //Wait for a connection
    sockaddr_in client;
    int clientSize = sizeof(client);

    SOCKET clientsocket = accept(listening, (sockaddr*)&client, &clientSize);

    char host[NI_MAXHOST];  //Clients remote name
    char service[NI_MAXHOST];   //Service the client is on

    ZeroMemory(host, NI_MAXHOST);
    ZeroMemory(service, NI_MAXHOST);

    if (getnameinfo((sockaddr*)&client, sizeof(client), host, NI_MAXHOST, service, NI_MAXSERV, 0) == 0)
    {
        cout << host << "connected on port " << service << endl;
    }
    else {
        inet_ntop(AF_INET, &client.sin_addr, host, NI_MAXHOST);
        cout << host << " connected on port " << ntohs(client.sin_port) << endl;
    }

    //Close listening socket
    closesocket(listening);

    //While loop:accept and echo message back to client
    char buf[4096];

    while (true)
    {
        ZeroMemory(buf, 4096);

        //Wait for client to send data
        int bytesReceived = recv(clientsocket, buf, 4096, 0);
        if (bytesReceived == SOCKET_ERROR)
        {
            cerr << "Error in recv()" << endl;
            break;
        }

        if (bytesReceived == 0)
        {
            cout << "Client disconnected" << endl;
            break;
        }

        cout << buf << endl;
    }

    //Close the socket
    closesocket(clientsocket);

    //cleanup windsock
    WSACleanup();
}

As I said, this code works as an individual project however, when I include this into my overall project the socket fails to open and a connection to 204.204.204.204 is instantly made. This was checked in both situations by viewing all open sockets with netstat. I feel this may be a library conflict, maybe between WS2_32 and libcurl, however I am unsure.

I am currently testing this by calling TCPServer() in my main, however I plan to run the server threaded along with my other processes.

Any suggestions as to why the socket may be failing to open would be much appreciated.


Solution

  • After carrying out checks on the function it was possible to narrow the failure down to the bind(...) function. It seems the error is down to having using namespace std;

    The solution was to call bind from the global namespace by doing ::bind(...). This solution was found here: Compilation errors with socket bind function