c - How would I go about making this udpclient asynchronous using pthreads? -


how go making udpclient asynchronous using pthreads? want make sure udp datagram won't lost , don't want client program wait forever , not able send more messages

/*udpclient.c program */

#include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef win #include <winsock.h> #include <windows.h> #endif #ifndef win #include <sys/types.h> #include <arpa/inet.h> #include <sys/socket.h> #endif /* here details of sockaddr_in structure , sockaddr structure    these declarations copied winsock.h     struct in_addr {       struct holds 32 bit ip address         union {                 struct { u_char s_b1,s_b2,s_b3,s_b4; } s_un_b;                 struct { u_short s_w1,s_w2; } s_un_w;                 u_long s_addr;         } s_un; #define s_addr  s_un.s_addr      struct sockaddr_in {   notice structure 16 bytes long             short       sin_family;             u_short     sin_port;             struct      in_addr sin_addr;             char        sin_zero[8];      };         struct sockaddr {       generic address structure 16 bytes long, too!             u_short sa_family;             char        sa_data[14];      };  */ /* have send on same port server listening on */ #define port 20009 /* simple upd client */ int main() { #ifdef win       socket sock; #else       int sock; #endif       int size;       int nbytes, flags;       int i;       char * cp; #ifdef win       wsadata wsadata;       int ncode; #endif       char buffer[100];       char str_addr[20];        /* holds chars of ip address */       struct sockaddr_in target_pc, me;  /* magic call initialize network i/o code - microsoft requires */ #ifdef win       if((ncode = wsastartup(makeword(1,1), &wsadata)) != 0){       printf("opps! wsa error %d\n",ncode);       return -1;       } #endif /* create socket send on */       sock = socket(pf_inet,sock_dgram,0);        if(sock < 0) {        printf("socket error = %d\n", sock);        return -1;        }       /* fill in address family , port, not know destination ip address yet */       target_pc.sin_family = pf_inet;       target_pc.sin_port = htons(port);       /* fill in address , port */       me.sin_family = pf_inet;       me.sin_port = htons(0);       me.sin_addr.s_addr = htonl(inaddr_any);       = bind(sock, (struct sockaddr *) &me, sizeof(me));       if( < 0) {           printf("bind result: %d\n", i);           return -1;           }         nbytes = 99;        while(1){             printf("enter target ip address: ");             cp = fgets(str_addr,19,stdin);             /* remove \n */             str_addr[strlen(str_addr)-1] = '\0';             /* inet_addr function converts string form of ip address 32 binary integer */             target_pc.sin_addr.s_addr = inet_addr(&str_addr[0]);             printf("enter message: ");             cp = fgets(buffer,99,stdin);             /* string length send many characters */             nbytes = strlen(buffer);             flags = 0;             size = sendto(sock, (char *) buffer, nbytes,flags,(struct sockaddr *)&target_pc,sizeof(target_pc));             printf("msg size = %d size = %d\n", nbytes, size);              //added              int addrlen = sizeof(target_pc);             size = recvfrom(sock, buffer, nbytes, flags, (struct sockaddr *)&target_pc,&addrlen);             if((size > 0) && (size < 99)){                buffer[size] = '\0';      //add null byte buffer holds string                 = puts((char *) buffer);    // write string display              }        } #ifdef win       system("pause"); #endif       return 0; } 

/udpserver.c program/

#include <stdio.h> #include <stdlib.h> #include <errno.h> #ifdef win #include <winsock.h> #include <windows.h> #endif #ifndef win #include <sys/types.h> #include <arpa/inet.h> #include <sys/socket.h> #endif #define port 20009 /* simple upd server     program receives short messages (<99 characters) ip address    , writes them display    sure use linker line option "-l wsock32" */ int main() {     /* first define socket     socket i/o port file descriptor     */ #ifdef win       socket sock;   /* socket typedef structure */ #else       int sock; #endif       int size;       int nbytes, flags; #ifdef win       int addrlen; #else       socklen_t addrlen; #endif       int i;       /* char loopback[20]="127.0.0.1"; */ #ifdef win       wsadata wsadata;              /* struct holds windows required data */       int ncode; #endif       char buffer[100];       struct sockaddr_in server;    /* holds ip address , port info */       struct sockaddr_in from;      /* holds same info sender of packet                                        received */       /* call wsastartup windows magic */ #ifdef win       if((ncode = wsastartup(makeword(1,1), &wsadata)) != 0){       printf("opps! wsa error %d\n",ncode);       exit;       } #endif       /* create socket called sock. datagram socket */       sock = socket(af_inet,sock_dgram,0);        if(sock < 0){        printf("socket error = %d\n", sock);        return -1;        }       server.sin_family = af_inet;   /* initialize server address family */       server.sin_addr.s_addr = htonl(inaddr_any); /* notice struct within struct */       /* printf("%x\n",server.sin_addr.s_addr); */       server.sin_port = htons(port);       /* associate socket address structure - called binding */       = bind(sock, (struct sockaddr *) &server, sizeof(server));       if( < 0) {           printf("bind result: %d\n", i);           return -1;           } else           printf("simple udp server ready!\n\n");       nbytes = 99; /* receive packets 99 bytes long */        flags = 0;  /* must 0 or not work! */       while(1){       /* recvfrom function read , arguments are:              sock - socket reading              buffer - array read data              nbytes - read many bytes              flags - used special purposes - not needed here              - sockaddr struct hold ip address , port of sender of packet              addrlen - size of sockaddr struct written function       */          addrlen = sizeof(from);          size = recvfrom(sock, buffer, nbytes, flags, (struct sockaddr *)&from, &addrlen);          if((size > 0) && (size < 99)){          buffer[size] = '\0';      /* add null byte buffer holds string */          = puts((char *) buffer);    /* write string display */          }           //echo message client           if(sock < 0) {//              printf("socket error = %d\n", sock);//              return -1;//          }//           sendto(sock, buffer, nbytes, flags, (struct sockaddr *)&from,addrlen); //       }  #ifdef win       system("pause"); #endif       return 0; } 

we create 2 threads: 1 sendto (that waits user input) , other recvfrom(). next, can have recvrom() use pthread condvar (by calling pthread_cond_wait() on condvar , pthread mutex) , wait. when user provides input, can sendto (which not blocking) , call pthread_cond_signal() wake other thread.

you this, if wanted. if application permits, skip pthread_cond_wait() since recvfrom() anyways blocking call. so, way, recvfrom() block go out of sync send calls. other option use main() thread sendto() thread -- in case, need 1 additional thread recv calls.


Comments

Popular posts from this blog

plot - Remove Objects from Legend When You Have Also Used Fit, Matlab -

java - Why does my date parsing return a weird date? -

Need help in packaging app using TideSDK on Windows -