C Programming
 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
User Name:
Password:
Remember me

The Shed is going Social! Join us on FaceBook and Twitter and chime in on the conversation.

Go Back   Dev Shed ForumsProgramming LanguagesC Programming

Reply
Add This Thread To:
  Del.icio.us   Digg   Google   Spurl   Blink   Furl   Simpy   Y! MyWeb 
Thread Tools Search this Thread Rate Thread Display Modes
 
Unread Dev Shed Forums Sponsor:
  #1  
Old February 3rd, 2013, 03:39 AM
brown_mist brown_mist is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Jan 2013
Posts: 1 brown_mist User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 1 m 51 sec
Reputation Power: 0
Multiple client connections

Hi,

I have a simple tcp server, to which i would like to add support for multiple client connections via pthreads. This is what i had in mind, calling accept in a separate thread.

I this similar to what you would do?
Code:
   .
   .
int sock = socket(PF_INET,SOCK_STREAM,0);
int sock_fd[10];
struct sockaddr_in client_addr[10];
int size = sizeof(&client_addr);

void *Thread1(void *arg){


   for(i=0;i<9;i++){
  sock_fd[i] = accept(sock,(struct sockaddr *)&client_addr[i],size);

}

Reply With Quote
  #2  
Old February 3rd, 2013, 02:19 PM
dwise1_aol's Avatar
dwise1_aol dwise1_aol is offline
Contributing User
Dev Shed God 2nd Plane (6000 - 6499 posts)
 
Join Date: Jan 2003
Location: USA
Posts: 6,142 dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level) 
Time spent in forums: 2 Months 2 Weeks 4 Days 6 m 41 sec
Reputation Power: 1974
OK, that's a start. How are you handling the client sockets?

Also, that array of client socket file descriptors is being changed by your accept thread by adding new clients, but somewhere else in your program it's also being changed by removing clients who have disconnected. That makes that array a critical region that needs to by synchronized. Also, keeping the client count as a local variable doesn't do that other portion of your code any good, nor any portion that has to make use of that array and hence know how many clients there are. If you make the client count a global as well, it will need to be part of the same critical region as the fd array.

Hopefully, none of what I just told you is new to you. If it is, then you might want to read up some more on the subject. A few years ago on my site I explored the topic of handling multiple sockets under the subject of dealing with blocking sockets. Here is a link to the multiprocessing/multithreading portion of that page: http://pgm.dwise1.net/sockets/blocking.html#THREADS. I haven't worked with it extensively, but maybe some of the ideas and the discussion might help.

Reply With Quote
  #3  
Old February 3rd, 2013, 10:51 PM
BobS0327 BobS0327 is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Oct 2012
Posts: 118 BobS0327 User rank is Sergeant Major (2000 - 5000 Reputation Level)BobS0327 User rank is Sergeant Major (2000 - 5000 Reputation Level)BobS0327 User rank is Sergeant Major (2000 - 5000 Reputation Level)BobS0327 User rank is Sergeant Major (2000 - 5000 Reputation Level)BobS0327 User rank is Sergeant Major (2000 - 5000 Reputation Level)BobS0327 User rank is Sergeant Major (2000 - 5000 Reputation Level) 
Time spent in forums: 3 Days 18 h 48 m 29 sec
Reputation Power: 44
Quote:
Originally Posted by brown_mist
Hi,

I have a simple tcp server, to which i would like to add support for multiple client connections via pthreads. This is what i had in mind, calling accept in a separate thread.

I this similar to what you would do?
Code:
   .
   .
int sock = socket(PF_INET,SOCK_STREAM,0);
int sock_fd[10];
struct sockaddr_in client_addr[10];
int size = sizeof(&client_addr);

void *Thread1(void *arg){


   for(i=0;i<9;i++){
  sock_fd[i] = accept(sock,(struct sockaddr *)&client_addr[i],size);

}


I just can't make the connection (no pun intended) between the code snippet you posted and implementing pthreads for a server. So, listed below is a bare bones server implementation using pthreads with some documentation.

Code:
// Compile gcc server.c -o server -lpthread
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <sys/uio.h>
#include <unistd.h>
#include <pthread.h>

// Port that we will be using
#define TCP_PORT   6600

/* function prototypes and global variables */
void *child_thread(void * arg);
pthread_mutex_t lock;
// This is just a cumulative count of how many clients have connected
// since the server was started
int	cumtotalconnections;

int main(void)
{
    int sockfd, newsockfd, clientlength;
    struct sockaddr_in cli_addr, serv_addr;
    pthread_t chld_thread;

    if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
        fprintf(stderr,"server can't open socket\n"), exit(0);

    memset((char *) &serv_addr, 0, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    serv_addr.sin_port = htons(TCP_PORT);

    if(bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
        fprintf(stderr,"server can't bind local address\n"), exit(0);
    // The OS threading library maintains a pool of Light Weight Processes, LWPs that it uses to run
    // all the process-scoped user threads.
    // It can reschedule these user threads onto LWPs in the pool as the need arises.
    // The size of this pool can be adjusted via the Pthreads pthread_setconcurrency() function.
    pthread_setconcurrency(5);
    listen(sockfd, 5);
    for(;;) {
        clientlength = sizeof(cli_addr);
        newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clientlength);

        if(newsockfd < 0)
            fprintf(stderr,"server has an accept error\n"), exit(0);

        /* create a new thread to process the incomming request */
        pthread_create(&chld_thread, NULL, child_thread, (void *)newsockfd);
        // the server is now free to accept another socket request
        // since pthread_create is a asynchronous function
    }
    return(0);
}

// Function executed from a new thread

void *child_thread(void *arg)
{
    int 	socketfd = (int) arg;
    char 	data[124]= {0};

    printf("Child thread [%d]: Socket number = %d\n", (int)pthread_self(), socketfd);
    /* read from the given socket */
    read(socketfd, data, 48);
    printf("Child thread [%d]: My data = %s\n", (int)pthread_self(), data);
	// POSIX threads defines a new data type called a mutex, which stands for mutual exclusion.
	// A mutex is used to insure either that only one thread is executing a particular piece of code at
	// once (code locking) or that only one thread is accessing a particular data structure at once (data locking).
	// A mutex belongs either to a particular thread or to no thread (i.e., it is either locked or unlocked).
	// A thread may lock a mutex by calling pthread_mutex_lock. If no other thread has the mutex locked,
	// then the calling thread obtains the lock on the mutex and returns. Otherwise it waits until no other thread has the mutex,
	// and finally returns with the mutex locked. There may, of course, be multiple threads waiting for the mutex to be unlocked.
	// Only one thread can lock the mutex at a time; there is no specified order for which thread gets the mutex next,
	// though the ordering is assumed to be at least somewhat fair.
	// To unlock a mutex, a thread calls pthread_mutex_unlock.

	// use a mutex to update the global cumtotalconnections

    pthread_mutex_lock(&lock);
    cumtotalconnections++;
    pthread_mutex_unlock(&lock);
    /* close the socket and exit this thread */
    close(socketfd);
    pthread_exit((void *)0);
}

Reply With Quote
Reply

Viewing: Dev Shed ForumsProgramming LanguagesC Programming > Multiple client connections

Developer Shed Advertisers and Affiliates



Thread Tools  Search this Thread 
Search this Thread:

Advanced Search
Display Modes  Rate This Thread 
Rate This Thread:


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
View Your Warnings | New Posts | Latest News | Latest Threads | Shoutbox
Forum Jump

Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
  
 


Powered by: vBulletin Version 3.0.5
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.

© 2003-2013 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap