/* sender for internet datagram demo */ /* modification 9/20/93 with Louis Sanchez's bug fix */ #include #include #include #include #include #define DATA 1 #define ACK 2 #define NORMAL 0 #define LOSEODD 1 #define LOSEEVEN 2 struct Msg { struct sockaddr_in dst; struct sockaddr_in src; char msgtype; char buf[80]; char alternating_bit; } help_msg() { printf("format: channel -[doe]\n"); printf(" option: d set debug on\n"); printf(" option: o lose every other messages (odd number ones)\n"); printf(" option: e lose every other messages (even number ones)\n"); } void printsockaddr(struct sockaddr_in *arg) { struct hostent *hp; printf(" sockaddr_in: "); printf("Domain=%d, ", arg->sin_family); hp=gethostbyaddr((const char *)&(arg->sin_addr), sizeof(arg->sin_addr), AF_INET); printf("Hostname=%s, ", hp->h_name); printf("Port=%d, ", ntohs(arg->sin_port)); printf("Address=%s,\n", inet_ntoa(arg->sin_addr)); } main(argc, argv) int argc; char *argv[]; { int sock; struct sockaddr_in from; int n; struct Msg m; extern char *optarg; extern int optind; int option_exist = 0; int c; int counter = 1; int length; int flag = 1; int behavior = NORMAL; int debug = 0; /* process command line args */ while ((c=getopt(argc,argv,"deo")) != EOF) { option_exist = 1; switch(c) { case 'o': behavior = LOSEODD; printf("Channel will lose odd numbered messages. (1,3,5)\n"); break; case 'e': behavior = LOSEEVEN; printf("Channel will lose even numbered messages. (2,4,6)\n"); break; case 'd': debug = 1; printf("set debug mode on\n"); break; case '?': help_msg(); exit (1); default: fprintf (stderr, "unrecognized arg >%s<\n", optarg); help_msg(); exit (1); } } /* create socket from which to read */ sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock < 0) { perror("opening datagram socket"); exit(1); } /* create name structure with wildcard using INADDR_ANY */ from.sin_family = AF_INET; from.sin_addr.s_addr = INADDR_ANY; from.sin_port = 0; /* port no. < 1024 IPPORT_RESERVED is for privillege process */ /* here just initialized it, it will be assigned value after call */ /* getsockname() */ if (bind(sock, &from, sizeof(struct sockaddr_in))) { perror("binding name to datagram socket"); exit(1); } length = sizeof(from); if (getsockname(sock, &from, &length)) { perror("getting socket name"); exit(1); } /* Find assigned port value and print out. */ printf("socket has port #%d\n", ntohs(from.sin_port)); while (flag) { n = recv(sock, &m, sizeof(m), 0); if (n < 0) perror("receiving datagram message"); printf("number of bytes received=%d\n", n); printf("m.msgtype=%d\n", m.msgtype); if (m.msgtype == DATA) printf("\treceived data msg=%s\n", m.buf); if (m.msgtype == ACK) printf("\treceived ack msg\n"); printf("\talternating bit is %d\n", m.alternating_bit); m.dst.sin_family = AF_INET; if (debug) { printsockaddr(&m.dst); } if (behavior == LOSEODD && counter%2 != 0) { printf("lose odd number message, msg #%d\n", counter); } else if (behavior == LOSEEVEN && counter%2 ==0) { printf("lose even number message, msg #%d\n", counter); } else { if (sendto(sock, &m, n, 0, &m.dst, sizeof(m.dst))<0) perror("relay datagram message"); } counter++; } close(sock); }