Search code examples
c++visual-studiotcp

Getting an error wile trying to open a TCP socket - c++


enter image description here

I'm trying to build a block that acts as server and client to send and receive data (2 duplicate versions in 2 different computers) through a TCP connection.

This is what I did and I'm trying to test using the windows commandd line "netstat -ab" to try to find the tcp connection but I can't find it.

Apart from the given error, what am i doing wrong?

bool IPTunnel::runBlock(void) {
    int ready =
        inputSignals[0]->ready(); // int ready2 = inputTCPConnetion[0]->ready();

    // server
    SOCKET sockfd, newsockfd;
    int portno;
    socklen_t clilen;
    char buffer[256];
    struct sockaddr_in serv_addr, cli_addr;
    SOCKET n;

    // create a socket(int domain, int type, int protocol)
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if(sockfd < 0) printf("\n ERROR opening socket");


    // bzero((char *)&serv_addr, sizeof(serv_addr));

    portno = 5500;


    serv_addr.sin_family = AF_INET;
    char ipad[10] = "127.0.0.1";
    serv_addr.sin_addr.s_addr = *ipad; // INADDR_ANY;
    serv_addr.sin_port = htons(portno);



    // if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
    auto sd = bind(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
    // if (sd < 0)
    //  printf("\n ERROR on binding");


    listen(sockfd, 5);

    clilen = sizeof(cli_addr);

    newsockfd = accept(sockfd, (struct sockaddr*)&cli_addr, &clilen);
    if(newsockfd < 0) printf("ERROR on accept");

    printf("server: got connection from %s port %d\n",
           inet_ntop(serv_addr.sin_family, &ipad, buffer, clilen),
           ntohs(cli_addr.sin_port));

    send(newsockfd, "Hello, world!\n", 13, 0);

    // bzero(buffer, 256);

    n = _read(newsockfd, buffer, 255);
    if(n < 0) printf("ERROR reading from socket");
    printf("Here is the message: %s\n", buffer);
    while(true) {
    }
    // close(newsockfd);
    // close(sockfd);
    return 0;
}

This is the error that gives: Unhandled exception at 0x00007FFE5031B7EC (ucrtbased.dll) in ip_tunnel.exe: An invalid parameter was passed to a function that considers invalid parameters fatal.

in the _read function...


Solution

  • Well, this line is definitely wrong:

    serv_addr.sin_addr.s_addr = *ipad; //INADDR_ANY;
    

    If you want to receive incoming TCP connections on the loopback device, you should do something more like this:

    serv_addr.sin_addr.s_addr = inet_aton("127.0.0.1");
    

    (or if you want them to be received from any connected network device, specify INADDR_ANY instead)

    Also, make sure you called WSAStartup() at the beginning of your program, Windows sockets won't work correctly if you haven't done that.

    One last nitpick:

    while(true){}
    

    is not a good way to pause execution of your program. For one thing, it will typically spin a CPU at 100% usage, which is very inefficient, and for another, it invokes undefined behavior according to the C++ standard.

    A better way to do get that behavior would be something like:

    while(true) {Sleep(1000);}
    

    Also this part is wrong/weird:

    SOCKET n;
    [...]
    n = _read(newsockfd, buffer, 255);
    

    ... in that _read doesn't return a SOCKET, it returns an int. I think you meant to declare int n; instead.

    One last potential problem: if your call to bzero(buffer, 256); is commented out, then it's quite possible for buffer to contain no zero-bytes after the _read() call returns, in which case your printf("Here is the message: %s\n", buffer); call afterwards could read right past the end of the buffer array and out into the wild blue yonder of other memory, potentially causing a crash (or at least causing a lot of garbage bytes to be printed). The fix is to make sure the buffer array contains a 0/NUL byte at the end of the valid bytes that were placed there by the _read() call.