#ifndef HW_SOCKET_H_ #define HW_SOCKET_H_ #include "hplatform.h" #include "hdef.h" #ifdef _MSC_VER #pragma comment(lib, "ws2_32.lib") #endif BEGIN_EXTERN_C // socket -> setsockopt -> bind -> listen // @return sockfd int Listen(int port); // gethostbyname -> socket -> nonblocking -> connect // @return sockfd int Connect(const char* host, int port, int nonblock DEFAULT(0)); // @param cnt: ping count // @return: ok count // @note: printd $CC -DPRINT_DEBUG int Ping(const char* host, int cnt DEFAULT(4)); #ifdef OS_WIN typedef int socklen_t; static inline int blocking(int sockfd) { unsigned long nb = 0; return ioctlsocket(sockfd, FIONBIO, &nb); } static inline int nonblocking(int sockfd) { unsigned long nb = 1; return ioctlsocket(sockfd, FIONBIO, &nb); } #define poll WSAPoll #define sockerrno WSAGetLastError() #define NIO_EAGAIN WSAEWOULDBLOCK #else #define blocking(s) fcntl(s, F_SETFL, fcntl(s, F_GETFL) & ~O_NONBLOCK) #define nonblocking(s) fcntl(s, F_SETFL, fcntl(s, F_GETFL) | O_NONBLOCK) #define closesocket close #define sockerrno errno #define NIO_EAGAIN EAGAIN #endif static inline int tcp_nodelay(int sockfd, int on DEFAULT(1)) { return setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (const char*)&on, sizeof(int)); } static inline int tcp_nopush(int sockfd, int on DEFAULT(1)) { #ifdef TCP_NOPUSH return setsockopt(sockfd, IPPROTO_TCP, TCP_NOPUSH, (const char*)&on, sizeof(int)); #elif defined(TCP_CORK) return setsockopt(sockfd, IPPROTO_TCP, TCP_CORK, (const char*)&on, sizeof(int)); #else return -10; #endif } static inline int tcp_keepalive(int sockfd, int on DEFAULT(1), int delay DEFAULT(60)) { if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (const char*)&on, sizeof(int)) != 0) { return sockerrno; } #ifdef TCP_KEEPALIVE return setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPALIVE, (const char*)&delay, sizeof(int)); #elif defined(TCP_KEEPIDLE) // TCP_KEEPIDLE => tcp_keepalive_time // TCP_KEEPCNT => tcp_keepalive_probes // TCP_KEEPINTVL => tcp_keepalive_intvl return setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPIDLE, (const char*)&delay, sizeof(int)); #else return 0; #endif } static inline int udp_broadcast(int sockfd, int on DEFAULT(1)) { return setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, (const char*)&on, sizeof(int)); } // send timeout static inline int so_sndtimeo(int sockfd, int timeout) { #ifdef OS_WIN return setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, (const char*)&timeout, sizeof(int)); #else struct timeval tv = {timeout/1000, (timeout%1000)*1000}; return setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); #endif } // recv timeout static inline int so_rcvtimeo(int sockfd, int timeout) { #ifdef OS_WIN return setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof(int)); #else struct timeval tv = {timeout/1000, (timeout%1000)*1000}; return setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); #endif } END_EXTERN_C #endif // HW_SOCKET_H_