1
0

hsocket.h 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. #ifndef HW_SOCKET_H_
  2. #define HW_SOCKET_H_
  3. #include "hplatform.h"
  4. #include "hdef.h"
  5. #ifdef _MSC_VER
  6. #pragma comment(lib, "ws2_32.lib")
  7. #endif
  8. BEGIN_EXTERN_C
  9. static inline int socket_errno() {
  10. #ifdef OS_WIN
  11. return WSAGetLastError();
  12. #else
  13. return errno;
  14. #endif
  15. }
  16. char* socket_strerror(int err);
  17. // socket -> setsockopt -> bind -> listen
  18. // @return sockfd
  19. int Listen(int port);
  20. // gethostbyname -> socket -> nonblocking -> connect
  21. // @return sockfd
  22. int Connect(const char* host, int port, int nonblock DEFAULT(0));
  23. // @param cnt: ping count
  24. // @return: ok count
  25. // @note: printd $CC -DPRINT_DEBUG
  26. int Ping(const char* host, int cnt DEFAULT(4));
  27. #ifdef OS_WIN
  28. typedef int socklen_t;
  29. static inline int blocking(int sockfd) {
  30. unsigned long nb = 0;
  31. return ioctlsocket(sockfd, FIONBIO, &nb);
  32. }
  33. static inline int nonblocking(int sockfd) {
  34. unsigned long nb = 1;
  35. return ioctlsocket(sockfd, FIONBIO, &nb);
  36. }
  37. #define poll WSAPoll
  38. #undef EAGAIN
  39. #define EAGAIN WSAEWOULDBLOCK
  40. #undef EINPROGRESS
  41. #define EINPROGRESS WSAEINPROGRESS
  42. #else
  43. #define blocking(s) fcntl(s, F_SETFL, fcntl(s, F_GETFL) & ~O_NONBLOCK)
  44. #define nonblocking(s) fcntl(s, F_SETFL, fcntl(s, F_GETFL) | O_NONBLOCK)
  45. #define closesocket close
  46. #endif
  47. static inline const char* sockaddr_ntop(const struct sockaddr* addr, char *ip, int len) {
  48. if (addr->sa_family == AF_INET) {
  49. struct sockaddr_in* sin = (struct sockaddr_in*)addr;
  50. return inet_ntop(AF_INET, &sin->sin_addr, ip, len);
  51. }
  52. else if (addr->sa_family == AF_INET6) {
  53. struct sockaddr_in6* sin6 = (struct sockaddr_in6*)addr;
  54. return inet_ntop(AF_INET6, &sin6->sin6_addr, ip, len);
  55. }
  56. return ip;
  57. }
  58. static inline uint16_t sockaddr_htons(const struct sockaddr* addr) {
  59. if (addr->sa_family == AF_INET) {
  60. struct sockaddr_in* sin = (struct sockaddr_in*)addr;
  61. return htons(sin->sin_port);
  62. }
  63. else if (addr->sa_family == AF_INET6) {
  64. struct sockaddr_in6* sin6 = (struct sockaddr_in6*)addr;
  65. return htons(sin6->sin6_port);
  66. }
  67. return 0;
  68. }
  69. static inline void sockaddr_printf(const struct sockaddr* addr) {
  70. char ip[INET6_ADDRSTRLEN] = {0};
  71. int port = 0;
  72. if (addr->sa_family == AF_INET) {
  73. struct sockaddr_in* sin = (struct sockaddr_in*)addr;
  74. inet_ntop(AF_INET, &sin->sin_addr, ip, sizeof(ip));
  75. port = htons(sin->sin_port);
  76. }
  77. else if (addr->sa_family == AF_INET6) {
  78. struct sockaddr_in6* sin6 = (struct sockaddr_in6*)addr;
  79. inet_ntop(AF_INET6, &sin6->sin6_addr, ip, sizeof(ip));
  80. port = htons(sin6->sin6_port);
  81. }
  82. printf("%s:%d\n", ip, port);
  83. }
  84. static inline const char* sockaddr_snprintf(const struct sockaddr* addr, char* buf, int len) {
  85. int port = 0;
  86. if (addr->sa_family == AF_INET) {
  87. struct sockaddr_in* sin = (struct sockaddr_in*)addr;
  88. inet_ntop(AF_INET, &sin->sin_addr, buf, len);
  89. port = htons(sin->sin_port);
  90. }
  91. else if (addr->sa_family == AF_INET6) {
  92. struct sockaddr_in6* sin6 = (struct sockaddr_in6*)addr;
  93. inet_ntop(AF_INET6, &sin6->sin6_addr, buf, len);
  94. port = htons(sin6->sin6_port);
  95. }
  96. char sport[16] = {0};
  97. snprintf(sport, sizeof(sport), ":%d", port);
  98. safe_strncat(buf, sport, len);
  99. return buf;
  100. }
  101. static inline int tcp_nodelay(int sockfd, int on DEFAULT(1)) {
  102. return setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (const char*)&on, sizeof(int));
  103. }
  104. static inline int tcp_nopush(int sockfd, int on DEFAULT(1)) {
  105. #ifdef TCP_NOPUSH
  106. return setsockopt(sockfd, IPPROTO_TCP, TCP_NOPUSH, (const char*)&on, sizeof(int));
  107. #elif defined(TCP_CORK)
  108. return setsockopt(sockfd, IPPROTO_TCP, TCP_CORK, (const char*)&on, sizeof(int));
  109. #else
  110. return -10;
  111. #endif
  112. }
  113. static inline int tcp_keepalive(int sockfd, int on DEFAULT(1), int delay DEFAULT(60)) {
  114. if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (const char*)&on, sizeof(int)) != 0) {
  115. return socket_errno();
  116. }
  117. #ifdef TCP_KEEPALIVE
  118. return setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPALIVE, (const char*)&delay, sizeof(int));
  119. #elif defined(TCP_KEEPIDLE)
  120. // TCP_KEEPIDLE => tcp_keepalive_time
  121. // TCP_KEEPCNT => tcp_keepalive_probes
  122. // TCP_KEEPINTVL => tcp_keepalive_intvl
  123. return setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPIDLE, (const char*)&delay, sizeof(int));
  124. #else
  125. return 0;
  126. #endif
  127. }
  128. static inline int udp_broadcast(int sockfd, int on DEFAULT(1)) {
  129. return setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, (const char*)&on, sizeof(int));
  130. }
  131. // send timeout
  132. static inline int so_sndtimeo(int sockfd, int timeout) {
  133. #ifdef OS_WIN
  134. return setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, (const char*)&timeout, sizeof(int));
  135. #else
  136. struct timeval tv = {timeout/1000, (timeout%1000)*1000};
  137. return setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
  138. #endif
  139. }
  140. // recv timeout
  141. static inline int so_rcvtimeo(int sockfd, int timeout) {
  142. #ifdef OS_WIN
  143. return setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof(int));
  144. #else
  145. struct timeval tv = {timeout/1000, (timeout%1000)*1000};
  146. return setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
  147. #endif
  148. }
  149. END_EXTERN_C
  150. #endif // HW_SOCKET_H_