The Shed is going Social! Join us on FaceBook and Twitter and chime in on the conversation.
|
 |
|
Dev Shed Forums
> Programming Languages
> C Programming
|
Multiple client connections
Discuss Multiple client connections in the C Programming forum on Dev Shed. Multiple client connections C programming forum discussing all C derivatives, including C#, C++, Object-C, and even plain old vanilla C. These languages are low level languages, and used on projects such as device drivers, compilers, and even whole computer operating systems.
|
|
 |
|
|
|
|

Dev Shed Forums Sponsor:
|
|
|

February 3rd, 2013, 03:39 AM
|
|
Registered User
|
|
Join Date: Jan 2013
Posts: 1
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);
}
|

February 3rd, 2013, 02:19 PM
|
 |
Contributing User
|
|
Join Date: Jan 2003
Location: USA
|
|
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.
|

February 3rd, 2013, 10:51 PM
|
|
|
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);
}
|
Developer Shed Advertisers and Affiliates
| Thread Tools |
Search this Thread |
|
|
|
| Display Modes |
Rate This Thread |
Linear Mode
|
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
|
|