/* NAME: UDP.ECHO.CLIENT SYNOPSIS: UDPClient hostid portnumber DESCRIPTION: The program creates a datagram socket in the inet domain, gets messsages typed by a user and sends them to echoserver running on hostid Then it waits for a reply from the echoserver and shows it back to the user, with a message indicating if there is an error during the round trip. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define BUF_SIZE 500 #define MAXHOSTNAME 80 int main(int argc, char * argv[]) { struct addrinfo hints, *result, *rp; struct addrinfo hints_local, *result_local; int sfd, s, s2, rc; struct sockaddr_storage peer_addr; socklen_t peer_addr_len; ssize_t nread; char buf[BUF_SIZE]; char ThisHost[MAXHOSTNAME]; if (argc < 2) { fprintf(stderr, "Usage: %s host port \n", argv[0]); exit(EXIT_FAILURE); } gethostname(ThisHost, MAXHOSTNAME); /*Obtain address(es) matching localhost/localport*/ memset(&hints_local, 0, sizeof(hints_local)); hints_local.ai_family = AF_INET; //IPv4 hints_local.ai_socktype = SOCK_DGRAM; //UDP hints_local.ai_flags = AI_PASSIVE; if (getaddrinfo(ThisHost, argv[2], &hints_local, &result_local) != 0) { fprintf(stderr, "getaddrinfo error\n"); exit(EXIT_FAILURE); } printf("----EchoClient running at host NAME: %s\n", ThisHost); printf("(EchoClient INET ADDRESS is: %s )\n", inet_ntoa(((struct sockaddr_in*)result_local->ai_addr)->sin_addr)); /*Obtain address(es) matching host/port*/ memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; //IPv4 hints.ai_socktype = SOCK_DGRAM; //UDP hints.ai_flags = AI_PASSIVE; if (getaddrinfo(argv[1], argv[2], &hints, &result) != 0) { fprintf(stderr, "getaddrinfo error\n"); exit(EXIT_FAILURE); } /* getaddrinfo() returns a list of address structures. Try each address until we successfully connect(2). If socket(2) (or connect(2)) fails, we (close the socket and) try the next address. */ for (rp = result; rp != NULL; rp = rp->ai_next) { sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); if (sfd == -1) continue; if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -1) break; /* Success */ close(sfd); } freeaddrinfo(result); /* No longer needed */ if (rp == NULL) { /* No address succeeded */ fprintf(stderr, "Could not connect\n"); exit(EXIT_FAILURE); } /* Send remaining command-line arguments as separate datagrams, and read responses from server. */ printf("----EchoServer running at host NAME: %s\n", argv[1]); printf("(EchoServer INET ADDRESS is: %s )\n", inet_ntoa(((struct sockaddr_in*)rp->ai_addr)->sin_addr)); for (;;) { printf("\nType anything followed by RETURN, or type CTRL-D to exit\n"); /* +1 for terminating null byte */ rc=read(0,buf, sizeof(buf)-1); buf[rc] = '\0'; if (rc == 0) break; peer_addr_len = sizeof(peer_addr); if (write(sfd, buf, rc) != rc) { fprintf(stderr, "partial/failed write\n"); exit(EXIT_FAILURE); } nread = recvfrom(sfd, buf, BUF_SIZE, 0, (struct sockaddr *)&peer_addr, &peer_addr_len); buf[nread]='\0'; if (nread == 1) { continue; //Ignore failed request } if (nread == -1) { perror("read"); exit(EXIT_FAILURE); } char host[NI_MAXHOST], service[NI_MAXSERV]; s2 = getnameinfo((struct sockaddr *)&peer_addr, peer_addr_len, host, NI_MAXHOST, service, NI_MAXSERV, NI_NUMERICSERV); if (s2 == 0) { printf("Received: %s from %s:%s\n", buf, host, service); } else fprintf(stderr, "getnameinfo: %s\n", gai_strerror(s)); } exit(EXIT_SUCCESS); }