0
votes

I am implementing a simple multithreaded FTP client server where I am facing a problem which is strange for me( as I am no master in C++ and threads).

The code I have written works normally until I #include <thread>.

Once I include the thread class the program fails on listen and gives a 10022 error. (I haven't done anything related to threads yet, only import).

Below is the code. The method is called from main().

#include <winsock2.h>
#include <ws2tcpip.h>
#include <process.h>
#include <winsock.h>
#include <iostream>
#include <windows.h>
#include <fstream>
#include <string>
#include <stdio.h>
#include <time.h>
#include <thread>

using namespace std;

void initializeSockets()
    {
    try{
        logEvents("SERVER", "Initializing the server");
        WSADATA wsadata;
        if (WSAStartup(0x0202,&wsadata)!=0){
            cout<<"Error in starting WSAStartup()\n";
            logEvents("SERVER", "Error in starting WSAStartup()");
        }else{

            logEvents("SERVER", "WSAStartup was suuccessful");
        }

        gethostname(localhost,20);
        cout<<"hostname: "<<localhost<< endl;
        if((hp=gethostbyname(localhost)) == NULL) {
            cout << "gethostbyname() cannot get local host info?"
                << WSAGetLastError() << endl;
            logEvents("SERVER", "Cannot get local host info. Exiting....");
            exit(1);
        }

        //Create the server socket
        if((serverSocket = socket(AF_INET,SOCK_STREAM,0))==INVALID_SOCKET) 
            throw "can't initialize socket";

        //Fill-in Server Port and Address info.
        serverSocketAddr.sin_family = AF_INET;
        serverSocketAddr.sin_port = htons(port);
        serverSocketAddr.sin_addr.s_addr = htonl(INADDR_ANY);

        //Bind the server port
        if (bind(serverSocket,(LPSOCKADDR)&serverSocketAddr,sizeof(serverSocketAddr)) == SOCKET_ERROR)
            throw "can't bind the socket";
        cout << "Bind was successful" << endl;
        logEvents("SERVER", "Socket bound successfully.");

        if(listen(serverSocket,10) == SOCKET_ERROR)
            throw "couldn't set up listen on socket";
        else 
            cout << "Listen was successful" << endl;
        logEvents("SERVER", "Socket now listening...");
        //Connection request accepted.
        acceptUserConnections();
    }

    catch(char* desc)
    { 
        cerr<<str<<WSAGetLastError()<<endl;
        logEvents("SERVER", desc);
    }

    logEvents("SERVER", "Closing client socket...");
    closesocket(clientSocket);
    logEvents("SERVER", "Closed. \n Closing server socket...");
    closesocket(serverSocket);
    logEvents("SERVER", "Closed. Performing cleanup...");

    WSACleanup();

}

int main(void){

    initializeSockets();
    return 0;
}

I have read the thread Winsock Error 10022 on Listen but I don't think that this has solution to my problem.

1
Where's the #include line? - Harry Johnston
included the includes :) - user3275095

1 Answers

4
votes

Error 10022 is WSAEINVAL. The documentation for listen() clearly states:

WSAEINVAL
The socket has not been bound with bind.

The reason your code stops working when you add #include <thread> is because your call to bind() is being altered to no longer call WinSock's bind() function, but to instead call the STL's std::bind() function. Your using namespace std statement is masking that issue (this is one of many reasons why using namespace std is such a bad practice - teach yourself to stop using that!).

So you need to either:

  1. get rid of using namespace std.

  2. qualify bind() with the global namespace so it calls WinSock's function:

    if (::bind(...) == SOCKET_ERROR)