C ++ Sockets - server does not accept multiple clients (linux)

I have a working server and client code. The server and client can correctly connect and communicate with each other. But when I open another client terminal, the client says Awaiting confirmation from the server and nothing more. Although server and client # 1 can still communicate.

I was looking for multithreading, but the examples or code snippets that they show are advanced. Maybe a little explanation or an example will help a lot!

The code below works. I have a working server, but it only accepts one connection. How to force the server to allow multiple connections? So that I can make the program look like a group chat.

client.cpp (when client # 2 connects, code hangs on line 40)

 #include <iostream> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> #include <stdlib.h> #include <unistd.h> using namespace std; int main() { char a; int client; int portNum = 1500; int bufsize = 1024; char* buffer = new char[bufsize]; bool isExit = false; char* ip = "127.0.0.1"; struct sockaddr_in direc; if ((client = socket(AF_INET, SOCK_STREAM, 0)) < 0) { cout << "\nError creating socket..." << endl; exit(0); } cout << "\nSocket created successfully..." << endl; direc.sin_family = AF_INET; direc.sin_port = htons(portNum); inet_pton(AF_INET, ip, &direc.sin_addr); if (connect(client,(struct sockaddr *)&direc, sizeof(direc)) == 0) cout << "Connection to the server " << inet_ntoa(direc.sin_addr) << endl; cout << "Awaiting confirmation from the server..." << endl; //line 40 recv(client, buffer, bufsize, 0); cout << "\n=> Enter # to terminate the connection\n" << endl; do { cout << "Client: "; do { cin >> buffer; send(client, buffer, bufsize, 0); if (*buffer == '#') { send(client, buffer, bufsize, 0); *buffer = '*'; isExit = true; } } while (*buffer != 42); cout << "Server: "; do { recv(client, buffer, bufsize, 0); cout << buffer << " "; if (*buffer == '#') { *buffer = '*'; isExit = true; } } while (*buffer != 42); cout << endl; } while (!isExit); cout << "=> Connection terminated.\nGoodbye"; close(client); return 0; } 

server.cpp

 #include <iostream> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <stdlib.h> #include <unistd.h> using namespace std; int main() { int client, server; int bufsize = 1024; int portNum = 1500; bool isExit = false; char* buffer = new char[bufsize]; struct sockaddr_in direc; socklen_t tamano; pid_t pid; if ((client = socket(AF_INET, SOCK_STREAM, 0)) < 0) { cout << "\nError establishing socket..." << endl; exit(1); } cout << "\nSocket server has been created..." << endl; direc.sin_family = AF_INET; direc.sin_addr.s_addr = htons(INADDR_ANY); direc.sin_port = htons(portNum); if ((bind(client, (struct sockaddr*)&direc,sizeof(direc))) < 0) { cout << "\nError binding connection..." << endl; return -1; } tamano = sizeof(direc); cout << "Looking for clients..." << endl; listen(client, 1); while ((server = accept(client,(struct sockaddr *)&direc,&tamano)) > 0) { strcpy(buffer, "Server connected...\n"); send(server, buffer, bufsize, 0); cout << "Connected with the client, you are good to go..." << endl; cout << "Enter # to end the connection\n" << endl; cout << "Client: "; do { recv(server, buffer, bufsize, 0); cout << buffer << " "; if (*buffer == '#') { *buffer = '*'; isExit = true; } } while (*buffer != '*'); do { cout << "\nServer: "; do { cin >> buffer; send(server, buffer, bufsize, 0); if (*buffer == '#') { send(server, buffer, bufsize, 0); *buffer = '*'; isExit = true; } } while (*buffer != '*'); cout << "Client: "; do { recv(server, buffer, bufsize, 0); cout << buffer << " "; if (*buffer == '#') { *buffer == '*'; isExit = true; } } while (*buffer != '*'); } while (!isExit); cout << "\n=> Connection terminated... " << inet_ntoa(direc.sin_addr); close(server); cout << "\nGoodbye..." << endl; isExit = false; } close(client); return 0; } 

How to make the server accept multiple connections?

Thanks!

+7
c ++ linux sockets
source share
2 answers

To properly support multiple connections, you must start a new thread for each incoming connection. Each new connection is identified by its own unique socket descriptor returned by accept() . A simple example:

 while ((accepted = accept(client,(struct sockaddr *)&direc,&tamano)) > 0) { /*Create the thread and pass the socket descriptor*/ if( pthread_create(new_thread, &thread_attributes, &handle_tcp_connection, (void *)accepted) != 0){ perror("create thread"); exit(EXIT_FAILURE); } } 
+3
source share

You will need to use select or poll and the automaton pattern to do what you want to do. This means that you will need to process the data as it arrives from the one who sends it. Look here for a working example.

+3
source share

All Articles