/* this is a UDP sender */ #include #include #include #include #include #include #include #include #include #include #define DATA_FRAME 1 #define ACK_FRAME 2 #define PACKETSIZE 10000 /* NOTE that as we have discussed earlier, the way to send packets over a socket is incorrect. You should consider this code as more an example on illustrating the reliable communication over unreliable channel, or underlying layer. The way to send data framework is incorrect, because it did not consider the common issues when sending a data structure over a socket, including data type size, host order, and alignment etc. */ struct frame { int seq; int type; int size; char buf[PACKETSIZE]; } myframe, ackframe; int main(int argc, char *argv[]) { int sockfd; struct sockaddr_in servaddr; char buf; int sendcount=0; if (argc < 3) { printf("Usage : a.out IPaddr port\n"); exit(0); } memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons((int)atoi(argv[2])); servaddr.sin_addr.s_addr = inet_addr(argv[1]); if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { perror(": socket"); exit(0); } { /* basic algorithm not reliability here */ int i; int myseq; fd_set rset; struct timeval timeout; buf = 'A'; myseq = 0; for (i=0; i< 1000; i++) { /* put packet in a frame */ myframe.size = 1; myframe.seq = myseq ++; myframe.type = DATA_FRAME; myframe.buf[0] = buf; sendto(sockfd, &myframe, sizeof(myframe)-PACKETSIZE+myframe.size, 0, (struct sockaddr *)&servaddr, sizeof(servaddr)); sendcount++; buf++; if (buf == 'Z'+1) buf = 'A'; FD_ZERO(&rset); FD_SET(sockfd, &rset); timeout.tv_sec = 0; timeout.tv_usec = 10000; do { while (select(64, &rset, NULL, NULL, &timeout) == 0) { /* retransmission */ sendto(sockfd, &myframe, sizeof(myframe)-PACKETSIZE+myframe.size, 0, (struct sockaddr *)&servaddr, sizeof(servaddr)); sendcount++; FD_ZERO(&rset); FD_SET(sockfd, &rset); timeout.tv_sec = 0; timeout.tv_usec = 10000; } recvfrom(sockfd, &myframe, sizeof(myframe), 0, NULL, NULL); if (myframe.type != ACK_FRAME) { printf("Something is wrong.\n"); exit(0); } printf("Receive ack %d\n", myframe.seq); } while (myframe.seq != myseq -1); /* my break here is the sequence number wrap around */ } sleep(3); for (i=0; i<4; i++) { buf = '+'; myframe.size = 1; myframe.seq = myseq ++; myframe.type = DATA_FRAME; myframe.buf[0] = buf; sendto(sockfd, &myframe, sizeof(myframe)-PACKETSIZE+myframe.size, 0, (struct sockaddr *)&servaddr, sizeof(servaddr)); sleep(2); } } printf("Total send = %d\n", sendcount); }