Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 680
  • Last Modified:

Unix C multi socket/Thread program

I'm working on a socket program for Unix Socket type AF_UNIX
I can get the socket to connect and communicate but I'm trying to use threads
to handle the communication after the connection is established.

I want to be able to have multiple socket connections and use threads to handle
servicing of the connections
any suggestions?
0
Valious
Asked:
Valious
  • 2
  • 2
1 Solution
 
rooster_0429Commented:
Please be a little more specific. Do you want a client that connects to multiple servers or do you want a server that can handle multiple incoming connections. I can give you some example code of a server or a client if you're more specific. Or if you post your code I can tell you what to add or fix.
0
 
ValiousAuthor Commented:
Sorry, for being vague, the portion I'm working on is the server program.
I trying to have the server wait for a connection/accept it then pass the socket descriptor to a thread where the thread will handle the communication with the client. Then the server will then wait for another connection and pass the new connection to a new thread.
0
 
rooster_0429Commented:
Well there's a good way to do this kind of thing and thats with threads. Which have become the standard for good server application programming practices. This is an ideal way to do it. But if you don't have to worry about shared memory then you may consider using the unix system call fork(). basically the parent process would just wait until a connection is made then fork and the forked process can handle the request. But this really only works for simple server applications. As to doing it in a multithreading fashion here is a sample server application I wrote. Basically it just waits for a client to make aconnection then hands that request off to a thread to be processed. The thread then just sends the current date and time to the client. There is also a thread that will allow the administrator to enter commands to the server. In this case tell it when to close down.

#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <time.h>

#define MYPORT 6029
#define NAMEPORT 6030
#define MAXDATASIZE 100
#define BACKLOG 5

#ifdef DEBUG
#define D(x) x
#else
#define D(x)
#endif

pthread_t c_listener, cmd_thread;
pthread_t threads[500]; //max 500 threads can run before errors occur. should be sufficient
int newfd[500];// max 500 sockets open for client requests before errors.
int mainfd;
char* NAMESERVER;

//global variable used to signal program termination
int loop = 1;

void* request_handler(int*);
void* client_listener(int*);
void* server_cmd(void*);

//enter the command line args: <my address> <nameservers address>
int main(int argc, char* argv[]){
  int sockfd;
  struct hostent* he;
  struct sockaddr_in their_addr;
  struct sockaddr_in my_addr;
  int sin_size, rc;
  int nullop  = 0;
  char buf[MAXDATASIZE];
  char* myLoc;

  D(printf("Debug feature is on.\n"););

  myLoc = argv[1];
  NAMESERVER = argv[2];  

  //register with the name server
  he = gethostbyname(NAMESERVER);
  their_addr.sin_family = AF_INET;
  their_addr.sin_port = htons(NAMEPORT);
  their_addr.sin_addr = *((struct in_addr*)he->h_addr);
  memset(&(their_addr.sin_zero),'\0',8);
  sockfd = socket(AF_INET, SOCK_STREAM, 0);
  connect(sockfd,(struct sockaddr*)&their_addr, sizeof(struct sockaddr));
  if(rc == -1){
    printf("dateServer: Connection to nameserver failed\n");
    exit(0);
  }//end if
  recv(sockfd,buf,MAXDATASIZE,0);
  printf("%s\n",buf);
  send(sockfd, "login", 6, 0);
  recv(sockfd, buf, MAXDATASIZE, 0);
  D(printf("%s\n", buf););
  send(sockfd, myLoc, strlen(myLoc)+1, 0);
  recv(sockfd, buf, MAXDATASIZE, 0);
  D(printf("%s\n", buf););
  send(sockfd, "date", 5, 0);
  recv(sockfd, buf, MAXDATASIZE, 0);
  printf("%s\n", buf);
  close(sockfd);
 
  //create threads
  pthread_create(&cmd_thread, NULL, server_cmd, (void *)0);
  pthread_create(&c_listener, NULL, client_listener, (void*)0);
  printf("waiting for client requests...\n");

  //null operation loop for main thread
  while(loop){
    nullop++;
    nullop--;
  }
  exit(0);
}//end main

void* client_listener(int* threadid){
  struct sockaddr_in their_addr;
  struct sockaddr_in my_addr;
  int sin_size;
  int t = 0;

  //set up socket to listen for connections
  D(printf("client_listener thread scheduled\n"););
  mainfd = socket(AF_INET, SOCK_STREAM,0);
  my_addr.sin_family = AF_INET;
  my_addr.sin_port = htons(MYPORT);
  my_addr.sin_addr.s_addr = INADDR_ANY;
  memset(&(my_addr.sin_zero),'\0',8);
  bind(mainfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr));
  listen(mainfd,BACKLOG);
 
  //when new connections are made spawn off a new thread
  while(loop){
    newfd[t] = accept(mainfd,(struct sockaddr *)&their_addr,&sin_size);
    pthread_create(&threads[t % 500], NULL, request_handler, (void*)(t%500));
    t++;
  }//end while
  pthread_detach(c_listener);
  //close(mainfd);
}//end client_listener

void* request_handler(int* threadid){
  int sockfd;
  time_t current_Time;

  sockfd = newfd[(int)threadid];
  time(&current_Time);
  send(sockfd,ctime(&current_Time),30,0);
  close(sockfd);
  printf("Date sent\n");
  printf("waiting for client requests...\n");
}//end request_handler

void* server_cmd(void* threadid){
  char* cmd[100];
  D(printf("server_cmd thread scheduled\n"););
  while(1){
    scanf("%s", &cmd);
    if(strncmp(cmd, "quit", 4) == 0){
      D(printf("server_cmd thread exiting\n"););
      close(mainfd);
      loop = 0;
      pthread_detach(cmd_thread);
      break;
    }//end if
  }//end while
}//end server_cmd
0
 
ValiousAuthor Commented:
Thank you Your comments were very Helpful
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 2
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now