Note that there are some explanatory texts on larger screens.

plurals
  1. POtcp server with multiple clients sending message back to all connected clients
    text
    copied!<p>I have a tcp chat program: <code>server.c</code> and <code>client.c</code>.</p> <p>The server is in a <code>while(1)</code> loop and uses <code>select</code> to detect clients wanting to connect on it's socket. A new thread is then created for the accepted client and its socket descriptor is given as an argument for thread: <code>pthread_create (&amp;thread,NULL, do_something, (void *) &amp;socket_descriptor);</code></p> <p>When receiving a message from a client, the server should send this message to all connected clients. (not implemented this yet).</p> <p>Now I'm wondering how to do this. I absolutely need each accepted connection to be in a thread.</p> <p>I was thinking of using a <code>select</code> inside the <code>do_something</code> as well; will <code>select</code> detect if data is incoming on the socket descriptor? Or would you do it another way?</p> <p>edit: added code my code: </p> <pre><code>#include &lt;pthread.h&gt; #include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; #include &lt;unistd.h&gt; #include &lt;fcntl.h&gt; #include &lt;errno.h&gt; #include &lt;string.h&gt; #include "tcp_comm.h" #include &lt;sys/time.h&gt; #include &lt;sys/types.h&gt; #define BUFSIZE 1024 #define PORT 1234 void *do_something(void *a); int main (void){ Socket server = tcp_passive_open( PORT ); MySocket *s = (MySocket *)server; printf("Server socked_id (main): %i", s-&gt;sd); pthread_t thread; fd_set active_socketDescriptors,read_socketDescriptors; FD_ZERO(&amp;active_socketDescriptors); FD_SET(s-&gt;sd,&amp;active_socketDescriptors); while (1){ read_socketDescriptors = active_socketDescriptors; if (select (FD_SETSIZE, &amp;read_socketDescriptors, NULL, NULL, NULL) &lt; 0){ perror ("select"); exit (EXIT_FAILURE); } int i; for (i = 0; i &lt; FD_SETSIZE; ++i){ if (FD_ISSET (i, &amp;read_socketDescriptors)){ if (i == s-&gt;sd){ Socket client = tcp_wait_for_connection( server ); pthread_create (&amp;thread,NULL, do_something, (void *)client); FD_SET (s-&gt;sd, &amp;active_socketDescriptors); } else { } } } } tcp_close( server ); return 0; } void *do_something(void *client){ unsigned char input[BUFFER_SIZE]; pthread_detach(pthread_self()); MySocket *s = (MySocket *)client; printf("Client socked_id (thread): %i", s-&gt;sd); int j; while (1){ int nbytes = tcp_receive(client, input, BUFSIZE ); if (nbytes &lt;= 0){ if (nbytes ==0){ /* connection closed by client*/ printf("Client closed connection"); } else { /* other error*/ perror("tcp_receive"); } tcp_close(&amp;client); /*remove the socket descriptor from set in the main BRAINSTORM ABOUT THIS */ } else { /*data incoming */ printf("\nMessage from client: %s",input); } } return 0; } </code></pre> <p>edit 2: reformulation of problem I have to use threads (it not because of the system; linux) but because it's mandatory in the assignment to have a thread for each client. </p> <p>The problem i have specifically is that only the main thread can send the data recieved in each thread from each client to all clients because only the main thread has access to the set which contains the socket descriptors. </p> <p>edit3: what I need to add in each thread but I can't because of the s.thread and s.main being in different places &amp; the thread not knowing the set of the main. </p> <pre><code>for (j=0; j&lt;=FD_SETSIZE;j++){ if(FD_ISSET(j,&amp;active_socketDescriptors)){ if (j != s.thead &amp;&amp; j!=s.main){ tcp_send(j, (void*)input,nbytes); } } } </code></pre> <p>edit 4: I solved it this way: i have a dynamic array list where i put a list of connected clients with there socket descriptor. Inside the thread of the server (do something) I have the recieve blocking until it gets input then this input is send to all connected clients using there socket descriptor from the list which it loops trough. Inside the clients there is a thread listening and a thread sending.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload