#include #include #include #include #include "Practical.h" #include "ch4_common.h" int main(int argc, char **argv) { if (argc < 3 || argc > 4) { DieWithUserMessage("Parameter(s)", " []"); } char *server = argv[1]; char *echo_str = argv[2]; const size_t echo_str_len = sizeof(echo_str); if (echo_str_len > MAXSTRINGLENGTH) { DieWithUserMessage(echo_str, "string too long"); } char *server_port = (argc == 4) ? argv[3] : "echo"; struct addrinfo addr_criteria = { 0 }; addr_criteria.ai_family = AF_UNSPEC; addr_criteria.ai_socktype = SOCK_DGRAM; addr_criteria.ai_protocol = proto_get_num("udp"); struct addrinfo *serv_addr = nullptr; int ret = getaddrinfo(server, server_port, &addr_criteria, &serv_addr); if (ret != 0) { DieWithUserMessage("getaddrinfo() failed", gai_strerror(ret)); } int sock = socket( serv_addr->ai_family, serv_addr->ai_socktype, serv_addr->ai_protocol ); if (sock < 0) { DieWithSystemMessage("socket() failed"); } fputs("Sending to ", stdout); PrintSocketAddress(serv_addr->ai_addr, stdout); fputc('\n', stdout); ssize_t num_bytes = sendto( sock, echo_str, echo_str_len, 0, serv_addr->ai_addr, serv_addr->ai_addrlen ); if (num_bytes < 0) { DieWithSystemMessage("sendto() failed"); } else if (num_bytes != echo_str_len) { DieWithUserMessage("sendto() error", "sent unexpected amount of bytes"); } struct sockaddr_storage from_addr; socklen_t from_addr_len = sizeof(from_addr); char buf[MAXSTRINGLENGTH + 1]; num_bytes = recvfrom( sock, buf, MAXSTRINGLENGTH, 0, (struct sockaddr *) &from_addr, &from_addr_len ); if (num_bytes < 0) { DieWithSystemMessage("recvfrom() failed"); } else if (num_bytes != echo_str_len) { DieWithUserMessage("recvfrom() error", "received unexpected amount of bytes"); } if (!sock_addrs_equal(serv_addr->ai_addr, (struct sockaddr *) &from_addr)) { fputs("serv_addr: ", stdout); PrintSocketAddress(serv_addr->ai_addr, stdout); fputs("\nfrom_addr: ", stdout); PrintSocketAddress((struct sockaddr *) &from_addr, stdout); fputc('\n', stdout); DieWithUserMessage("recvfrom()", "received a packet from unkown source"); } freeaddrinfo(serv_addr); buf[echo_str_len] = '\0'; printf("Received: %s\n", buf); close(sock); return 0; }