Question

I want to write a tcp-listener within my application, so it can be controlled by others applications.

For that I use the following snippet I found (as an example for the use of listener).

I worked with p2p-connections and Sockets once already in C#.NET, but it's either too long ago or too differently. I expect the code to stop at the listen() command and wait until there is a connection request at that port. However, instead it just continues with the next lines. Usually my Firewall should also tell me, if there is some internet-activity-attempt, but it stays silent.

What would be the next step to actually know whether there is a connection request? Can I trigger that with a HTTP-request for 127.0.0.1:27015 using a browser? Or could this be archived easier?

#include <winsock.h>
#pragma comment(lib, "Ws2_32.lib")

int portlisten(){
    WSADATA wsaData;
    int iResult = 0;

    SOCKET ListenSocket = INVALID_SOCKET;
    sockaddr_in service;

    iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != NO_ERROR) {
        wprintf(L"WSAStartup() failed with error: %d\n", iResult);
        return 1;
    }
    //----------------------
    // Create a SOCKET for listening for incoming connection requests.
    ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (ListenSocket == INVALID_SOCKET) {
        wprintf(L"socket function failed with error: %ld\n", WSAGetLastError());
        WSACleanup();
        return 1;
    }
    //----------------------
    // The sockaddr_in structure specifies the address family,
    // IP address, and port for the socket that is being bound.
    service.sin_family = AF_INET;
    service.sin_addr.s_addr = inet_addr("127.0.0.1");
    service.sin_port = htons(27015);

    iResult = bind(ListenSocket, (SOCKADDR *) & service, sizeof (service));
    if (iResult == SOCKET_ERROR) {
        wprintf(L"bind function failed with error %d\n", WSAGetLastError());
        iResult = closesocket(ListenSocket);
        if (iResult == SOCKET_ERROR)
            wprintf(L"closesocket function failed with error %d\n", WSAGetLastError());
        WSACleanup();
        return 1;
    }
    //----------------------
    // Listen for incoming connection requests
    // on the created socket
    if (listen(ListenSocket, 5) == SOCKET_ERROR)
        wprintf(L"listen function failed with error: %d\n", WSAGetLastError());

    wprintf(L"Listening on socket...\n");

    iResult = closesocket(ListenSocket);
    if (iResult == SOCKET_ERROR) {
        wprintf(L"closesocket function failed with error %d\n", WSAGetLastError());
        WSACleanup();
        return 1;
    }

    WSACleanup();
    return 0;
}
Was it helpful?

Solution

I expect the code to stop at the listen() command and wait until there is a connection request at that port.

No. You are thinking of accept() instead. listen() merely opens the port and then exits immediately. You have to then use accept() in a loop to accept individual client connections. It returns a new SOCKET that you use to exchange data with that specific client. You can use select() to know when a new client is trying to connect before then calling accept(), or you can let accept() block the calling thread until a client connects.

Instead of writing your own socket API code, you should use a pre-existing TCP server component, like the VCL's native TServerSocket component, or Indy's TIdTCPServer component.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top