tod
tod

Reputation: 91

c socket programming

It is a code of server which is connected to a intermediate host which further connected to clients. The role of intermediate server is to take data from server or client and forward it on other side. Suppose there are two client asking for data(i.e.'a') so in my server two threads for periodic data is generated,but when any of the client want to quit it sends 'b' and on receiving 'b' both of threads get exited. So, can you suggest me some logic so that only a single thread is exited on one request(i.e. 'b').

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <pthread.h>


void* periodic(void* t);
void* oneshot(void* t);

char value='\0',control;
static pthread_mutex_t data_lock;
int no=0,count=0;

struct transfer
{
 int connec;
 struct sockaddr_in client;
};

pthread_t tid1,tid3;
int main(int argc,char *argv[])
{
    int sock, connected, bytes_recieved , flag,ret,true;
    struct sockaddr_in server_addr,client_addr;
    struct transfer t2,*t1=NULL;
    t1=&t2;
    int sin_size;
  /*here is normal connec stablishment between server and intermidiate host*/
    printf("\nTCPServer Waiting for client on port 5000");
    fflush(stdout);


    sin_size = sizeof(struct sockaddr_in);

    connected = accept(sock, (struct sockaddr *)&client_addr,&sin_size);


    printf("\n waiting for data request from server2:.......\n");
    fflush(stdout);

    pthread_mutex_init(&data_lock,0);

    t1->connec=connected;
    t1->client=client_addr;

    pthread_create(&tid3,NULL,recieve,(void*)t1);
    while(1){
            if(value=='\0')
             continue;
            if(value=='a')
             {
              pthread_create(&tid1,NULL,periodic,(void*)t1);
              count++;
              control=value;
              value='\0';
             }

            else if(value=='b')
            {
             control=value;
             pthread_join(tid1,NULL);
             value='\0';
            }
           }//end of while
    pthread_join(tid3,NULL);
    close(connected);

   }//end of main

   void* periodic(void* t)
  {
   struct transfer *t1=(struct transfer*)t;
   int data=100;
   printf("periodic");

     fflush(stdout);
     while(1){
            if(control=='b')
            {count--;
             data=0;
             send(t1->connec,&data,sizeof(data),0);
             printf("1 time\n");

             break;
            }
            pthread_mutex_lock(&data_lock);
            send(t1->connec,&data,sizeof(data),0);
            pthread_mutex_unlock(&data_lock);

            sleep(4);
            printf("coming\n");
           }
            printf("comming out\n");
            pthread_exit(NULL);
      }//end of periodic


      void* recieve(void *t)
        {
          struct transfer *t1=(struct transfer*)t;
          char control;

         while(1)
         {
          //control=value;
          recv(t1->connec,&value,1,0);
           //if(value!=control)
           printf("%c\n",value);

          }
          printf("out of recieve\n");

         fflush(stdout);

            pthread_exit(NULL);
         }//end of recieve

Upvotes: 0

Views: 385

Answers (2)

Mario The Spoon
Mario The Spoon

Reputation: 4869

This example is in no way safe or will function. value is a global variable that can and will be manipulated by all threads. The receive buffer must be create within the thread. Also, you created a busy loop in your main with the while loop waiting for value to change. If you have multiple client connections and one real data server inside that should answer the requests you must implement a client server model. Or if threads are too complex, take a look at select! .

Upvotes: 0

Dan Kruchinin
Dan Kruchinin

Reputation: 3055

Probably you shouldn't share the same "value" for both clients. It'd be better if you would have an array of clients and corresponding values. Client can be identified by sockaddr structure returned by accept (see client_addr).

Upvotes: 1

Related Questions