echo.cpp 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. #include <iostream>
  2. #include <stdio.h>
  3. #include <assert.h>
  4. #include <mutex>
  5. #include <map>
  6. #include <vector>
  7. #include <random>
  8. #include <chrono>
  9. #include <sys/types.h>
  10. #include <unistd.h>
  11. #include <sys/socket.h>
  12. #include <stdlib.h>
  13. #include <netdb.h>
  14. #include <arpa/inet.h>
  15. #include <netinet/in.h>
  16. #include <pthread.h>
  17. #include <string.h>
  18. using namespace std;
  19. typedef std::chrono::high_resolution_clock Clock;
  20. typedef std::chrono::milliseconds ms;
  21. typedef std::chrono::microseconds us;
  22. int resolvehelper(const char* hostname, int family, const char* service, sockaddr_storage* pAddr)
  23. {
  24. int result;
  25. addrinfo* result_list = NULL;
  26. addrinfo hints = {};
  27. hints.ai_family = family;
  28. hints.ai_socktype = SOCK_DGRAM; // without this flag, getaddrinfo will return 3x the number of addresses (one for each socket type).
  29. result = getaddrinfo(hostname, service, &hints, &result_list);
  30. if (result == 0)
  31. {
  32. //ASSERT(result_list->ai_addrlen <= sizeof(sockaddr_in));
  33. memcpy(pAddr, result_list->ai_addr, result_list->ai_addrlen);
  34. freeaddrinfo(result_list);
  35. }
  36. return result;
  37. }
  38. sockaddr_storage addrDest = {};
  39. int sock;
  40. Clock::time_point start = Clock::now();
  41. uint64_t packets = 0;
  42. uint64_t bytes = 0;
  43. int main(void) {
  44. int err;
  45. struct addrinfo hints, *res;
  46. //UDP host
  47. memset(&hints, 0, sizeof hints);
  48. hints.ai_family = AF_INET; // use IPv4
  49. hints.ai_socktype = SOCK_DGRAM;
  50. hints.ai_flags = AI_PASSIVE; // fill in my IP for me
  51. getaddrinfo(NULL, "1234", &hints, &res);
  52. sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
  53. err = bind(sock, res->ai_addr, res->ai_addrlen);
  54. if(err != 0) {
  55. printf("sock: %2d, err: %2d\n", sock, err);
  56. exit(1);
  57. }
  58. resolvehelper("localhost", AF_INET, "1234", &addrDest);
  59. while(1) {
  60. uint8_t buf[1500];
  61. int len;
  62. uint slen = sizeof(addrDest);
  63. len = recvfrom(sock, buf, 1500, 0, (sockaddr*)&addrDest, &slen);
  64. if(len<=0)
  65. continue;
  66. sendto(sock, buf, len, 0, (sockaddr*)&addrDest, sizeof(addrDest));
  67. bytes += len;
  68. packets++;
  69. if(len != 1024 || packets >= 10000 || chrono::duration_cast<ms>(Clock::now() - start).count() >= 1000) {
  70. int64_t delay = chrono::duration_cast<us>(Clock::now() - start).count();
  71. start = Clock::now();
  72. printf("sent %7lu packets with %10lu bytes = %9lu values in %8.3f ms (%8.3f MBit/s)\n", packets, bytes, bytes/4, delay/1000.0, delay/1000.0/1000.0 * bytes / 1024.0 / 1024.0 * 8);
  73. packets = 0;
  74. bytes = 0;
  75. }
  76. }
  77. }