/* alternating bit sender for internet datagram demo */ #include #include #include #include #include #define DATA 1 #define ACK 2 struct Msg { struct sockaddr_in dst; struct sockaddr_in src; char msgtype; char buf[80]; char alternating_bit; } ; help_msg() { printf("format: absender -[dn] rcvhost rcvportno c1host c1portno\n"); printf(" option: n set the number of messages to be sent\n"); printf(" option: d set debug mode\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; struct sockaddr_in to; struct hostent *hp, *gethostbyname(); struct Msg mto, mfrom; extern char *optarg; extern int optind; int option_exist = 0; int c; int length; int flag = 1; int debug = 0; int n = 5; int i; char *rcvHost; /* receiver's host name */ int rcvPortNo; char *C1Host; /* channel C1's host name */ int C1PortNo; char hostname[80]; /* process command line args */ while ((c=getopt(argc,argv,"dn:")) != EOF) { option_exist = 1; switch(c) { case 'n': if ((n = atoi(optarg)) < 1) n = 1; printf("The number of messages to be sent is %d\n", n); break; case 'd': debug = 1; printf("set debug mode on\n"); exit (1); default: fprintf (stderr, "unrecognized arg >%s<\n", optarg); help_msg(); exit (1); } } rcvHost = argv[optind++]; rcvPortNo = atoi(argv[optind++]); C1Host = argv[optind++]; C1PortNo = atoi(argv[optind++]); /* 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)); mto.src.sin_family = from.sin_family; mto.src.sin_port = from.sin_port; /* from.sin_addr.s_addr does not have the 4 byte internet address mto.src.sin_addr.s_addr = from.sin_addr.s_addr; replaced by the following code using gethostbyname() */ if (debug) printf("from.sin_addr.s_addr=%4x\n", from.sin_addr.s_addr); gethostname(hostname, sizeof(hostname)); hp = gethostbyname(hostname); if (hp == 0) { fprintf(stderr, "%s: unknown host",rcvHost); exit(2); } bcopy(hp->h_addr, &mto.src.sin_addr, hp->h_length); /* in system V unix use memcpy */ /* memcpy(&mto.dst.sin_addr, hp->h_addr, hp->h_length); */ if (debug) { printf("mto.src:"); printsockaddr(&mto.src); } /* construct name of the socket to send to * gethostbyname() returns a structure including the network address * of the specified host from /etc/hosts. The port number is taken from * the cmd line * create name structure for the UNIX domain socket * use the name from cmd argument */ hp = gethostbyname(rcvHost); if (hp == 0) { fprintf(stderr, "%s: unknown host",rcvHost); exit(2); } bcopy(hp->h_addr, &mto.dst.sin_addr, hp->h_length); printf("hp->h_length=%d\n", hp->h_length); /* in system V unix use memcpy */ /* memcpy(&mto.dst.sin_addr, hp->h_addr, hp->h_length); */ mto.dst.sin_family = AF_INET; mto.dst.sin_port = htons(rcvPortNo); if (debug) { printf("mto.dst:"); printsockaddr(&mto.dst); printf("mto.src:"); printsockaddr(&mto.src); } hp = gethostbyname(C1Host); if (hp == 0) { fprintf(stderr, "%s: unknown host", C1Host); exit(2); } bcopy(hp->h_addr, &to.sin_addr, hp->h_length); /* in system V unix use memcpy */ /* memcpy(&to.sin_addr, hp->h_addr, hp->h_length); */ to.sin_family = AF_INET; to.sin_port = htons(C1PortNo); bzero(mto.buf, sizeof(mto.buf)); /* in SysV UNIX, memset(mto.buf, 0, sizeof(mto.buf)); */ for (i=0; i