c - full duplex communication between server & client -


i want make code full duplex communication between server & client using code.
got error in receive-message thread server side & in send-message thread client side.
please me solve errors & suggest me if other changes required. :)

server.cpp

int newsockfd, n;  void error(const char *msg) {     perror(msg);     exit(1); }  void* recvfn( void* data ) {     char buffer[256];     while(n==0){      memset( buffer, sizeof(buffer), 0);         n = recv(newsockfd,buffer,255,msg_peek);         if(n>0){             printf("cliet: ");             printf("%s",buffer);             }      }     return null; }  void* sendfn( void* data ) {     char temp[255], buffer[255];     while(n==0){     memset( buffer, sizeof(buffer), 0);         fgets(temp,255,stdin);                           sprintf(buffer,"clent: %s",temp);         n = send(newsockfd,buffer,strlen(buffer),msg_eor);     }     return null; } int main(int argc, char *argv[]) {     int sockfd, portno;     socklen_t clilen;      struct sockaddr_in serv_addr, cli_addr;      if (argc < 2) {         fprintf(stderr,"error, no port provided\n");         exit(1);     }      pthread_t recvthread, sendthread;      sockfd = socket(af_inet, sock_stream, 0);     if (sockfd < 0)          error("error opening socket");  memset( &serv_addr, sizeof(serv_addr), 0);     portno = atoi(argv[1]);     serv_addr.sin_family = af_inet;     serv_addr.sin_addr.s_addr = inaddr_any;     serv_addr.sin_port = htons(portno);      int on = 1;     if ( setsockopt( sockfd, sol_socket, so_reuseaddr, &on, sizeof( on ) ) != 0 ) {         close( sockfd );         return -1;     }       if (bind(sockfd, (struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)          error("error on binding");      listen(sockfd,5);      clilen = sizeof(cli_addr);     newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);     if (newsockfd < 0)          error("error on accept");          n = 0;         int rc;          rc = pthread_create( &recvthread, null, recvfn, null);         if(rc){             printf("error in receive-message thread\n");             return -1;         }           rc = pthread_create( &sendthread, null, sendfn, null);         if(rc){             printf("error in send-message thread\n");             return -1;         }          close(newsockfd);         close(sockfd);     pthread_cancel(recvthread);     pthread_cancel(sendthread);     return 0;  } 

client.cpp

int sockfd, n;  void* recvfn( void* data ) {     char buffer[255];     while( n==0 ){      memset( buffer, sizeof(buffer), 0);         n = recv(sockfd,buffer,255,msg_peek);         if(n>0){             printf("server: ");             printf("%s",buffer);             }     }     return null; }  void* sendfn( void* data ) {     char temp[255], buffer[255];     while( n==0 ){     memset( buffer, sizeof(buffer), 0);         fgets(temp,255,stdin);                           sprintf(buffer,"clent: %s",temp);         n = send(sockfd,buffer,strlen(buffer),msg_eor);      }     return null; }  void error(const char *msg) {     perror(msg);     exit(0); }  int main(int argc, char *argv[]) {     int  portno;     struct sockaddr_in serv_addr;     struct hostent *server;     char buffer[256];      if (argc < 3) {         fprintf(stderr,"usage %s hostname port\n", argv[0]);         exit(0);     }      pthread_t recvthread, sendthread;       sockfd = socket(af_inet, sock_stream, 0);     if (sockfd < 0)          error("error opening socket");      portno = atoi(argv[2]);     server = gethostbyname(argv[1]);     if (server == null) {         fprintf(stderr,"error, no such host\n");         exit(0);     }  memset( &serv_addr, sizeof(serv_addr), 0);     serv_addr.sin_family = af_inet; memcpy((char *)server->h_addr,(char *)&serv_addr.sin_addr.s_addr, server->h_length);     serv_addr.sin_port = htons(portno);       if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)          error("error on connecting");          n = 0;         int rc;         rc = pthread_create( &sendthread, null, sendfn, null);         if(rc){             printf("error in send-message thread\n");             return -1;         }          rc = pthread_create( &recvthread, null, recvfn, null);         if(rc){             printf("error in receive-message thread\n");             return -1;         }          close(sockfd);     pthread_cancel(recvthread);     pthread_cancel(sendthread);     return 0; } 

your pthread_mutex operations pointless. you're referring local variables inside mutex lock other n, should local in each thread , newsockfd should not global, see below. (don't think function calls recv should have local variable capture number of bytes read, , not share silly little temporary variable globally other threads?)

your main thread in while loop, creating threads crazy. also, inside loop has closed 1 , accepted socket, right after creating threads.

you forgot put accept inside loop, evidently.

also seem think main loop somehow wait pair of threads terminate before launching new ones. missing pthread_join calls wait threads finish communicating. if want thread keep going while main loop accepts new connections using new threads, should make threads detached pthread_detached or using thread-creation attribute makes them detached. non-detached threads not pthread_join-ed continue occupy resources.

speaking of shutdown, correct condition threads keep looping while n == 0? n set nonzero 1 of threads, shutdown condition met. nonzero value normal: bytes written or read. reader should terminate loop when there fatal receive error on socket, or read returns zero.

also, evaluating n == 0 outside of mutex!

if want accept multiple concurrent connections, each pair of threads, cannot use single global socket. have give each pair of threads own socket. 2 threads within each pair not have use mutex share socket. socket calls thread-safe in kernel , threads not both doing reads or writes; 1 reading , 1 writing.

other problems

your sender keeps sending uninitialized garbage: buffer never set contain data.

you have bzero of 256 bytes on array of 255 bytes.

also

don't use bzero (or bcopy, etc). it's bsd-ism 1980's. c language standardized in 1989 ansi , after in 1990 iso. @ time, had library functions memset, memcpy , memmove.

i think 22 years later, safe retire bcopy, dontcha think?


Comments

Popular posts from this blog

delphi - How to convert bitmaps to video? -

jasper reports - Fixed header in Excel using JasperReports -

python - ('The SQL contains 0 parameter markers, but 50 parameters were supplied', 'HY000') or TypeError: 'tuple' object is not callable -