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
Post a Comment