0

when I compile this program and run it, I get the output below. I added the bind failed with error output for debugging and it suggests that with the error code that I received from listen the socket is not bound using bind but the 0 output is confusing me as that is the output when everything worked. I would appreciate any suggestions

#define DefaultBufLen 1024
SOCKET Socket = INVALID_SOCKET;
int difficulty = 0;

WSADATA wsaData;
struct addrinfo* result = NULL,
    * ptr = NULL,
    hints;
sockaddr_in Service;

int recvbuflen = DefaultBufLen;
char SendBuf[DefaultBufLen] = "";
char RecvBuf[DefaultBufLen] = "";

if (WSAStartup(MAKEWORD(2, 2), &wsaData) != NO_ERROR) {
        wprintf(L"Startup failed with error code %d\n", WSAGetLastError());
        return 1;
    };

    Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (Socket == INVALID_SOCKET) {
        wprintf(L"Socket failed with error: %1d\n", WSAGetLastError());
        WSACleanup();
        return 1;
    };

    Service.sin_family = AF_INET;
    Service.sin_addr.s_addr = inet_addr("127.0.0.1");
    Service.sin_port = htons(27015);

    bind(Socket, (SOCKADDR*)&Service, sizeof(Service));
    wprintf(L"bind failed with error: %ld\n", WSAGetLastError());

    while (1) {
        if (listen(Socket, 2000) == SOCKET_ERROR) {
            wprintf(L"listen failed with error: %ld\n", WSAGetLastError());
            closesocket(Socket);
            WSACleanup();
            return 1;
        }
        else { 
            wprintf(L"listen succeeded!\n");
        }
        SOCKET AcceptingSocket;
        wprintf(L"Waiting for client to connect...\n");

        AcceptingSocket = accept(Socket, NULL, NULL);
        if (AcceptingSocket == INVALID_SOCKET) {
            wprintf(L"accept failed with error: %ld\n", WSAGetLastError());
            closesocket(Socket);
            WSACleanup();
            return 1;
        }
        else {
            wprintf(L"Client connected.\n");
        }

        int Error = 0;

        do {

            Error = recv(Socket, RecvBuf, recvbuflen, 0);
            if (Error > 0)
                printf("Bytes received: %d\n", Error);
            else if (Error == 0)
                printf("Connection closed\n");
            else
                printf("recv failed: %d\n", WSAGetLastError());

        } while (Error > 0);

        string TranslatedRecvBuf = RecvBuf;

        vector<string> Request;
        boost::split(Request, TranslatedRecvBuf, boost::is_any_of(";"));
        if (Request[0] == "RBlock") {
        Irrelevant
        else if (Request[0] == "DBlock") {
        Irrelevant
        else if (Request[0] == "TxIncl") {
        Irrelevant
        else if (Request[0] == "BaLook") {
        Irrelevant

        closesocket(AcceptingSocket);
    };
};

Output:

bind failed with error: 0
listen failed with error: 10022

[process exited with code 1 (0x00000001)]
  • 2000 is not a happy number. If you meant "a lot" then use SOMAXCONN instead. – Hans Passant Jul 31 '22 at 13:35
  • 2
    You are not checking the return value of `bind`. You should check it before printing an error message and calling `WSAGetLastError`. – Andreas Wenzel Jul 31 '22 at 13:36
  • I have changed the 2000 to SOMAXCONN, and have added ```else wprintf( L"listen succeeded!\n" );``` in the affected if statement and still the same output – Correctmite Jul 31 '22 at 14:32
  • The code after the ... is now posted in the question – Correctmite Jul 31 '22 at 14:33
  • With the bind returning I have tried to return it but it as it is in the documentation as an integer, but it returns a syntax error. Thats why I used the WSAGetLastError – Correctmite Jul 31 '22 at 14:41
  • 1
    You should replace `bind(Socket, (SOCKADDR*)&Service, sizeof(Service));` with `if ( bind(Socket, (SOCKADDR*)&Service, sizeof(Service)) != 0 )`, so that the line afterwards only gets executed on error. This should solve the error message of `bind`, but I don't think it will solve the error message of `listen`. – Andreas Wenzel Jul 31 '22 at 14:43
  • The behavior you describe does not make sense to me. Therefore, I suspect that the information you provided is not entirely accurate. Please provide a [mre] of the problem, which includes a function `main` and all `#include` directives. That way, we can test the program ourselves. If your claim is correct that the first call to `listen` is failing, then you should be able to create an example that reproduces the problem in which all code below `listen` is removed. – Andreas Wenzel Jul 31 '22 at 14:57
  • Oddly enough When I was making the minimal reproductive example the problem disappeared with everything removed except the winsock related code. Also, the bind solution you proposed still results in a syntax error – Correctmite Jul 31 '22 at 15:35
  • @Correctmite: Please post the exact error message from the compiler as well as the line with the call to `bind` and the line immediately below. You can post these lines as a comment, if you wish. – Andreas Wenzel Jul 31 '22 at 15:41
  • @Correctmite: Don't worry about the code not being properly formatted in the comment. I can sort it out. – Andreas Wenzel Jul 31 '22 at 16:18
  • Compiler:```Source2.cpp(342): error C2678: binary '!=': no operator found which takes a left-hand operand of type 'std::_Binder' (or there is no acceptable conversion) C:\Program Files (x86)\Windows Kits\10\\include\10.0.19041.0\\shared\guiddef.h(197): note: could be 'bool operator !=(const GUID &,const GUID &)' ``` Line: ```if (bind(Socket, (SOCKADDR*)&Service, sizeof(Service)) != 0) { wprintf(L"bind failed with error: %ld\n", WSAGetLastError()); }``` – Correctmite Jul 31 '22 at 16:18
  • @Correctmite: Are you maybe using `using namespace std;` in your code, so that the compiler has trouble distinguishing [`std::bind`](https://en.cppreference.com/w/cpp/utility/functional/bind) with Winsock2 `bind`? – Andreas Wenzel Jul 31 '22 at 16:21
  • @Correctmite: Does the problem disappear if you write `::bind` instead of `bind`? – Andreas Wenzel Jul 31 '22 at 16:23
  • I am using 'using namespace std' – Correctmite Jul 31 '22 at 16:23
  • It works now Thank you very much. It was getting confused how will I avoid this in the future? – Correctmite Jul 31 '22 at 16:24
  • 1
    @Correctmite: That is the disadvantage of using `using namespace std;`. It may be more convenient, but it creates ambiguities. You may want to read this: [Why is "using namespace std;" considered bad practice?](https://stackoverflow.com/q/1452721/12149471). – Andreas Wenzel Jul 31 '22 at 16:27
  • @Correctmite FYI, after you fix `bind()`, there are other problems in the code. *Don't* call `listen()` in the `while` loop, call it only 1 time after `::bind()` and before the loop. Also, your `recv()` loop is wrong. You are reading into `RecvBuf` until the client disconnects/fails, THEN you are processing `RecvBuf`. Your processing should be inside `if (Error > 0)`. And `RecvBuf` is *not* null-terminated, so `string TranslatedRecvBuf = RecvBuf;` is *undefined behavior*, use `string TranslatedRecvBuf(RecvBuf, Error);` instead. And you need to define a *protocol* for WHEN to stop reading. – Remy Lebeau Aug 02 '22 at 00:33
  • @RemyLebeau I only want to receive one thing from the connected client so would I remove the loop entirely and if it is an error or a failure it will pass over my conditions and be disregarded? As effectively when its running I wouldn't care about someone disconnecting. Thank you for the help. – Correctmite Aug 02 '22 at 16:06
  • "*would I remove the loop entirely*" - no, because `recv()` can return fewer bytes than requested, and you don't know how many bytes the client will send, so you need a loop, and pay attention to `recv`'s return value to act accordingly. But your loop is currently just overwriting `RecvBuf` on each iteration, you need to copy the contents somewhere else in between, say to a `std::string`, eg: `string TranslatedRecvBuf; int NumBytes; while ( (NumBytes = recv(Socket, RecvBuf, recvbuflen, 0)) > 0) { TranslatedRecvBuf.append(RecvBuf, NumBytes); } if (NumBytes < 0) { error handling ... }` – Remy Lebeau Aug 02 '22 at 18:31

0 Answers0