c - UDP server not responding to client -


working on program meant emulate data layers in networking. i've got messages coming through server correctly, however, client not receiving ack frame server. causing program wait endlessly. in fixing matter appreciated.

sender

#include <stdio.h> #include <unistd.h> #define maxframe  97 main(int argc, char* argv[]){     char *frame;     int len = 0;     int c;     dlinits("spirit.cba.csuohio.edu", 43525);     frame = malloc(maxframe);      file *file = fopen(argv[1], "r");     if (file == null)         return null;      while ((c = fgetc(file)) != eof)     {         if(len == (maxframe-1)){             dlsend(frame, len, 0);             len = 0;             memset(frame,0,strlen(frame));         }                 frame[len++] = (char) c;     }      dlsend(frame, len, 1);     } 

receiver

#include <string.h> #include <unistd.h> char* dlrecv();  main(){     char* test[100];     dlinitr(43525);     while(1){         strcpy(test,dlrecv());          printf("%s\n", test);     }   } 

data layer

#include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <fcntl.h> #include <errno.h> #include <stdio.h> #include <string.h> #include <unistd.h> #define bufmax 100  static int sk; static struct sockaddr_in remote; static struct sockaddr_in local; static int fnum = 0; static expfra = 0x00;  dlinits(char* host, int port){//initialize sender      struct hostent *hp;     sk = socket(af_inet, sock_dgram, 0);      remote.sin_family = af_inet;      hp = gethostbyname(host);     if (hp == null){         printf("can't find host name\n");         exit(1);     }      bcopy(hp->h_addr,&remote.sin_addr.s_addr,hp->h_length);      remote.sin_port = ntohs(port); }  dlinitr(int port){//initialize receiver     int rlen = sizeof(remote);     int len = sizeof(local);     char buf[bufmax];      sk = socket(af_inet,sock_dgram,0);      local.sin_family = af_inet;     local.sin_addr.s_addr = inaddr_any;     local.sin_port = htons(port);     bind (sk, &local,sizeof(local));      getsockname(sk,&local,&len);  }  dlsend(char* msg, int len, int end){//send data     int header = 0x00;     int result;     char *ackframe = malloc(3);     unsigned char *nmsg;     nmsg = malloc(100);     if ((fnum%2) == 1){         header = header|0x02;     }     if (end == 1){         header = header|0x40;     }     header = header^0xff;     printf("%x\n %x\n", header, 0);     nmsg[0] = (char)header;     len++;     printf("%s\n", nmsg);     memcpy(nmsg + 1, msg, strlen(msg));     result = crc(nmsg, len);     nmsg[len++] = ((result >> 8) & 0xff);     nmsg[len++] = (result & 0xff);       printf("%s\n", nmsg);     sendto(sk,nmsg,len,0,&remote,sizeof(remote));      read(sk,ackframe,3);     printf("ack received: %s\n", ackframe);      fnum++; }   char* dlrecv(){//receive data     int result;     int header;     int ack = 1;     char alen = 1;     char *ackframe = malloc(3);     unsigned char* msg = malloc(100);     while (ack){         recvfrom(sk,msg,bufmax,0,&remote,sizeof(remote));         int len = strlen(msg);         result = crc(msg, len);         if (result == 0){             msg[--len] = 0;             msg[--len] = 0;             header = msg[0];             printf("header %x expfra %x\n", header, expfra);             header = header^0xff;             printf("header %x expfra %x\n", header, expfra);             if ((header<<4) == (expfra<<4)){                 expfra = expfra^0x02;                 ackframe[0] = (0x10|header);                 result = crc(ackframe, alen);                 ackframe[alen++] = ((result >> 8) & 0xff);                 ackframe[alen++] = (result & 0xff);                 sendto(sk,ackframe,strlen(ackframe),0,&remote,sizeof(remote));                 printf("ack sent: %s\n", ackframe);                 ack = 0;              }         }     }     printf("%s\n", msg);     return ++msg; } 

edit moment these working on same machine. edit ran check using errno, returned error 22 sendto inside of dlrecv.

my experience udp has been read() (which you're using @ end of dlsend()) hit-or-miss, when paired sendto(). unless there's reason not it, changing read() recvfrom() should fix problem.

your code throws lot of warnings mismatched types. they're kinda-sorta harmless, make tracking else down more complicated.

after that, final acknowledgment-sendto() using bad socket data. poking around, reason you're passing integer in (sizeof(remote)) pointer address's size in previous recvfrom() call. if initial size given small, recvfrom() produces unreliable results. if needs less space that, it'll change value tell used.

so, need declare integer initialized size of sockaddr_in structure, , pass pointer last parameter. changes, assuming server arrives @ sendto() function (your sample has under single conditional branch), you'll right values address , able send acknowledgment.

the big lessons learned should (a) make sure types correct , review every warning , (b) check return value of every socket call , print error if -1 back.


Comments

Popular posts from this blog

java - WrongTypeOfReturnValue exception thrown when unit testing using mockito -

php - Magento - Deleted Base url key -

android - How to disable Button if EditText is empty ? -