How do I add threading to socket program?

Jul 21, 2009 at 1:52pm
Hi

I am 'trying' to get my head around multi-threaded programs. I have a working program (single thread) that uses a socket to listen on a particular port and exchange info with a client(s). The basic program structure is this (most declarations and error-checking removed for clarity):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
...
/* create a streaming socket */
simpleSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

int sockOp = setsockopt(simpleSocket, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
 	
 /* retrieve the port number for listening */
 simplePort = atoi(argv[1]);
 	
 /* setup the address structure */
 /* user INADDR_ANY to bind all local addresses */
 bzero(&simpleServer, sizeof(simpleServer));
 simpleServer.sin_family = AF_INET;
 simpleServer.sin_addr.s_addr = htonl(INADDR_ANY);
 simpleServer.sin_port = htons(simplePort);
 	
 /* bind to the address and port with our socket */
 returnStatus = bind(simpleSocket, (struct sockaddr *)&simpleServer, sizeof(simpleServer));

/* tell the socket we are ready to accept connections */
returnStatus = listen(simpleSocket, 5);

/* ACCEPT */
while (1) {
    /* block on accept function call */
    simpleChildSocket = accept(simpleSocket, (struct sockaddr *)&clientName, (socklen_t*)&clientNameLength);

    /* handle the new connection request */
    /* receive remote polling location ID from the client */
    int rcvBytes;
    unsigned char rcvBuffer[16600];
    rcvBytes = read(simpleChildSocket, rcvBuffer, sizeof(rcvBuffer));

    .... //do some more stuff

    /* close socket */
   close(simpleChildSocket);
} //while
...


So I am trying to adapt this but it doesn't seem to listen in a loop anymore. I am basing my multi-threaded structure on examples in the book "The Definitive Guide to Linux Network Programming" which has the following structure:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
...
void* thread_proc(void *arg);
...
pthread_t thread_id;

/* create a streaming socket */
simpleSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

int sockOp = setsockopt(simpleSocket, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
 	
 /* retrieve the port number for listening */
 simplePort = atoi(argv[1]);
 	
 /* setup the address structure */
 /* user INADDR_ANY to bind all local addresses */
 bzero(&simpleServer, sizeof(simpleServer));
 simpleServer.sin_family = AF_INET;
 simpleServer.sin_addr.s_addr = htonl(INADDR_ANY);
 simpleServer.sin_port = htons(simplePort);
 	
 /* bind to the address and port with our socket */
 returnStatus = bind(simpleSocket, (struct sockaddr *)&simpleServer, sizeof(simpleServer));

/* tell the socket we are ready to accept connections */
returnStatus = listen(simpleSocket, 5);

int result;

/* ACCEPT */
while (1) {
    simpleChildSocket = accept(simpleSocket,NULL, NULL);
    result = pthread_create(&thread_id, NULL, thread_proc, (void *) simpleChildSocket);

    pthread_detach(thread_id);
    sched_yield();

} //while

void* thread_proc(void *arg) {
  int sock = (int) arg;


    /* handle the new connection request */
    /* receive remote polling location ID from the client */
    int rcvBytes;
    unsigned char rcvBuffer[16600];
    rcvBytes = read(sock, rcvBuffer, sizeof(rcvBuffer));

    ....

    /* close socket */
   close(simpleChildSocket);
} //thread_proc 


Now, instead of finishing a loop and waiting for another connection, it just seems to hang and not accept any more connections.

What should the structure look like? I.e. When to listen, loop (while), create the thread, etc. so that after one client connects it continues to wait for and accept subsequent connections.

Thanks for looking.

Regards,
Scott
Jul 21, 2009 at 4:20pm
I did something like this:


create thread using myFunc
add it to pool
wait for all threads in pool to be done

/**myFunc**/
accept connection
make new thread
add new thread to pool
do connection handling stuff
close connection
Jul 21, 2009 at 5:12pm
I don't actually want this program to end. It should really be waiting for a socket connection, create a thread for that particular connection, do its thing, and then close the thread. I want to have a max. number of threads open at a time but want it to go on and on opening and closing threads. OR. Have x number of threads open, each waiting for a connection over the socket.

Which is the correct way of doing this.

If using a thread pool - you create the number of threads you want right away, correct?
Jul 21, 2009 at 5:47pm
as far as i know u can control the number of threads in a thread pool during its lifetime... but u can "command" all the threads like a single one due to this pool... correct me when im wrong^^...

let ur loop wait for an incomning connection and when it it accepts start a new thread and pass the socketnumber to it... then do any exchanges via that thread...
Jul 21, 2009 at 6:20pm
Incubbus: I thought I was waiting for a connection and starting a new thread (second piece of code in original post). It works with one thread, but can't get 1+ threads to work. The second thread seems to start right away, rather than waiting for a subsequent client to connect.

i.e.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

pthread_t thread1 thread2;

//create socket

//bind socket

//listen on socket

while (1) {
    //accept socket connection

    //create thread1
   //create thread2

   //detach threads

   //this is where I am unsure.  Do I create 1+ threads or create one thread and detach ??

} //while

void* thread_proc(void *arg) {
  //recv. on socket

  //do some stuff

  //close socket

} //thread_proc 
Jul 21, 2009 at 6:23pm
Here is what I would like to do - let me know if my logic is incorrect:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
...
pthread_t thread1 thread2;

//create socket

//bind socket

//listen on socket

while (1) {
    //accept socket connection

    /*create a thread, have it go on to thread_proc, then have this instance of while loop finish,
     * and return to the top of the while loop to wait for another connection, which creates 
     * another thread */

} //while

void* thread_proc(void *arg) {
  //recv. on socket

  //do some stuff

  //close socket

} //thread_proc  
Last edited on Jul 21, 2009 at 6:23pm
Topic archived. No new replies allowed.