UDPEchoServer.c 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. #include <sys/socket.h>
  2. #include <netdb.h>
  3. #include "Practical.h"
  4. #include "ch4_common.h"
  5. int main(int argc, char **argv) {
  6. if (argc != 2) {
  7. DieWithUserMessage("Parameter(s)", "<Server Port/Service");
  8. }
  9. char *service = argv[1];
  10. struct addrinfo addr_criteria = { 0 };
  11. addr_criteria.ai_family = AF_UNSPEC;
  12. addr_criteria.ai_flags = AI_PASSIVE;
  13. addr_criteria.ai_socktype = SOCK_DGRAM;
  14. addr_criteria.ai_protocol = proto_get_num("udp");
  15. struct addrinfo *serv_addr = nullptr;
  16. int ret = getaddrinfo(nullptr, service, &addr_criteria, &serv_addr);
  17. if (ret != 0) {
  18. DieWithUserMessage("getaddrinfo() failed", gai_strerror(ret));
  19. }
  20. int sock = socket(
  21. serv_addr->ai_family,
  22. serv_addr->ai_socktype,
  23. serv_addr->ai_protocol
  24. );
  25. if (sock < 0) {
  26. DieWithSystemMessage("socket() failed");
  27. }
  28. if (bind(sock, serv_addr->ai_addr, serv_addr->ai_addrlen) < 0) {
  29. DieWithSystemMessage("bind() failed");
  30. }
  31. fputs("Listening on ", stdout);
  32. PrintSocketAddress(serv_addr->ai_addr, stdout);
  33. fputc('\n', stdout);
  34. freeaddrinfo(serv_addr);
  35. while (true) {
  36. struct sockaddr_storage client_addr;
  37. socklen_t client_addr_len = sizeof(client_addr);
  38. char buf[MAXSTRINGLENGTH];
  39. const ssize_t num_bytes_recvd = recvfrom(
  40. sock,
  41. buf,
  42. MAXSTRINGLENGTH,
  43. 0,
  44. (struct sockaddr *) &client_addr,
  45. &client_addr_len
  46. );
  47. if (num_bytes_recvd < 0) {
  48. DieWithSystemMessage("recvfrom() failed");
  49. }
  50. fputs("Handling client ", stdout);
  51. PrintSocketAddress((struct sockaddr *) &client_addr, stdout);
  52. fputc('\n', stdout);
  53. const ssize_t num_bytes_sent = sendto(
  54. sock,
  55. buf,
  56. num_bytes_recvd,
  57. 0,
  58. (struct sockaddr *) &client_addr,
  59. client_addr_len
  60. );
  61. if (num_bytes_sent < 0) {
  62. DieWithSystemMessage("sendto() failed");
  63. } else if (num_bytes_sent != num_bytes_recvd) {
  64. DieWithUserMessage("sendto()", "sent unexpected number of bytes");
  65. }
  66. }
  67. }