1

So I am trying to implement a server-client system in C++17 that also uses multithreading to deal with the clients. Thus far I managed to implement a basic outliner of it using Winsock2 for the server connections and the windows specific threads (CreateThread(...), etc...). And it's working fine.

Though since C++11 implemented it's own threads and we want to be able to run the system on Linux as well I decided to implement the threads that way, so I don't have the hassle of dealing with possix.

But pretty much it screwed up my thing and I don't know how to fix it. (note I am currently trying this on a local server, with both the "server" and the "client" running on the same machine).

So originally the system looked something like :

//set up connection / server details
while(true){
    newConnection = accept(sListen, (SOCKADDR*)&addr, &addrlen);
    if (newConnection == 0)
        {
         std::cout<<"Failed to accept the client's connection."" <<std::endl;
        }
        else
        {
        CreateThread(...);
        }
}

The problem is that if I include thread or mutex newConnection will accept a connection 24/7 even if there is none and it will always go in the else of the if. If I don't include thread and mutex the else of the if will be activated only when a client connects to the server.

Any ideas on how I could fix this or what might cause this problem?

Cheers

EDIT :

SOCKADDR_IN addr;
int addrlen = sizeof(addr); 

inet_pton(AF_INET, "127.0.0.1", &ip_address);
addr.sin_addr.s_addr = ip_address;
addr.sin_port = htons(1111); //Port
addr.sin_family = AF_INET; //IPv4 Socket

SOCKET sListen = socket(AF_INET, SOCK_STREAM, NULL); 
bind(sListen, (SOCKADDR*)&addr, sizeof(addr)); 
listen(sListen, SOMAXCONN);

EDIT 2 : I think the problem is that if I don't include <thread> or <mutex> the accept actually waits for a client to connect before it proceeds, while if I include it it just returns INVALID_SOCKET which seems to be equal to 4294967295.

Bumblebee
  • 25
  • 5
  • is `sListen` in nonblocking mode? Show the code for creating it too. Btw, `accept` returns -1 on failure on posix systems. Any non-negative value == success. – Ted Lyngmo Nov 14 '18 at 12:47
  • I am currently runing this on Visual Studio and accept (if I would include or returns 4294967295. For slisten : SOCKET sListen = socket(AF_INET, SOCK_STREAM, NULL); bind(sListen, (SOCKADDR*)&addr, sizeof(addr)); listen(sListen, SOMAXCONN); – Bumblebee Nov 14 '18 at 12:49
  • Ok, then do `newConnection == INVALID_SOCKET` in your test. – Ted Lyngmo Nov 14 '18 at 12:51
  • I did that and it goes in thus I assume the socket is invalid. I think the problem is that if I don't include thread or mutex the accept actually waits for a client to connect before it proceeds, while if I include it it just returns INVALID_SOCKET which seems to be equal to 4294967295. And that's what I'm kinda stuck on I guess. – Bumblebee Nov 14 '18 at 12:55
  • Also it doesn't allow my client to connect at all. – Bumblebee Nov 14 '18 at 12:56
  • The protocol is NULL? Shouldn't it be `IPPROTO_TCP` – Ted Lyngmo Nov 14 '18 at 12:56
  • I've tried both NULL and IPPROTO_TCP, has exactly the same behaviour. – Bumblebee Nov 14 '18 at 12:59
  • Be sure that you check for errors the correct way. I don't know if `INVALID_SOCKET == 0` but it looks like one possible cause for taking the wrong decision. – Ted Lyngmo Nov 14 '18 at 13:01
  • Also show how the `sockaddr` struct is populated. – Ted Lyngmo Nov 14 '18 at 13:03
  • I've updated the main question with how the addr is populated. It's simply set to the default local address. INVALID_SOCKET seems to be equal to 4294967295, which is the max 32bit value of a uint. As I said in EDIT 2 : I think the main problem is that for some reason if those 2 libraries are included accept(...) does not wait for a client but just constantly returns INVALID_SOCKET and doesn't even let clients connect anymore. – Bumblebee Nov 14 '18 at 13:08
  • Ok, does `inet_pton` return `1` for success? If not, have you tried `InetPtonW` instead? – Ted Lyngmo Nov 14 '18 at 13:18
  • my inet_pton returns 1, thus is successful – Bumblebee Nov 14 '18 at 13:28
  • 2
    Do you have `using namespace std;` anywhere? What happens if you change `bind` to `::bind`? – G.M. Nov 14 '18 at 13:36
  • Thank you! That seems to do it. There are some other problems (was expected) but that ::bind seems to have done the trick for my main issue. I thought it might be related to it this morning, but when I commented it out I didn't realize I have to do ::bind. Would you mind telling me why it's ::bind? Also I don't really know how to mark a comment as the sollution, so if you comment it as an answer I will mark it as such. Thanks a lot to both of your for your help! – Bumblebee Nov 14 '18 at 13:50
  • Good catch! I'll remove my confusing answer. – Ted Lyngmo Nov 14 '18 at 13:55
  • @G.M. needs to add an answer and then you can accept it. – Ted Lyngmo Nov 14 '18 at 13:56

1 Answers1

5

Most implementations of the thread header will include (directly or otherwise) the functional header. That header declares std::bind. Unfortunately, if you also have...

using namespace std;

then there's a chance that std::bind will be preferred to the network related bind you're interested in.

See also Why is “using namespace std” considered bad practice?.

G.M.
  • 12,232
  • 2
  • 15
  • 18