hsocket.cpp 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. #include "hsocket.h"
  2. #ifdef OS_WIN
  3. class WinSocketRAII {
  4. public:
  5. WinSocketRAII() {
  6. WSADATA wsadata;
  7. WSAStartup(MAKEWORD(2,2), &wsadata);
  8. }
  9. ~WinSocketRAII() {
  10. WSACleanup();
  11. }
  12. };
  13. static WinSocketRAII s_ws;
  14. #endif
  15. int Listen(int port) {
  16. // socket -> setsockopt -> bind -> listen
  17. int listenfd = socket(AF_INET, SOCK_STREAM, 0);
  18. if (listenfd < 0) {
  19. perror("socket");
  20. return -10;
  21. }
  22. // note: SO_REUSEADDR means that you can reuse sockaddr of TIME_WAIT status
  23. int reuseaddr = 1;
  24. if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuseaddr, sizeof(int)) < 0) {
  25. perror("setsockopt");
  26. closesocket(listenfd);
  27. return -11;
  28. }
  29. struct sockaddr_in addr;
  30. socklen_t addrlen = sizeof(addr);
  31. memset(&addr, 0, addrlen);
  32. addr.sin_family = AF_INET;
  33. addr.sin_addr.s_addr = htonl(INADDR_ANY);
  34. addr.sin_port = htons(port);
  35. if (bind(listenfd, (struct sockaddr*)&addr, addrlen) < 0) {
  36. perror("bind");
  37. closesocket(listenfd);
  38. return -20;
  39. }
  40. if (listen(listenfd, SOMAXCONN) < 0) {
  41. perror("listen");
  42. closesocket(listenfd);
  43. return -30;
  44. }
  45. return listenfd;
  46. }
  47. int Connect(const char* host, int port, int nonblock) {
  48. // gethostbyname -> socket -> nonblocking -> connect
  49. struct sockaddr_in addr;
  50. socklen_t addrlen = sizeof(addr);
  51. memset(&addr, 0, addrlen);
  52. addr.sin_family = AF_INET;
  53. addr.sin_addr.s_addr = inet_addr(host);
  54. if (addr.sin_addr.s_addr == INADDR_NONE) {
  55. struct hostent* phe = gethostbyname(host);
  56. if (phe == NULL) return -10;
  57. memcpy(&addr.sin_addr, phe->h_addr, phe->h_length);
  58. }
  59. addr.sin_port = htons(port);
  60. int connfd = socket(AF_INET, SOCK_STREAM, 0);
  61. if (connfd < 0) {
  62. perror("socket");
  63. return -20;
  64. }
  65. if (nonblock) {
  66. nonblocking(connfd);
  67. }
  68. int ret = connect(connfd, (struct sockaddr*)&addr, addrlen);
  69. #ifdef OS_WIN
  70. if (ret < 0 && sockerrno != WSAEWOULDBLOCK) {
  71. #else
  72. if (ret < 0 && sockerrno != EINPROGRESS) {
  73. #endif
  74. perror("connect");
  75. closesocket(connfd);
  76. return -30;
  77. }
  78. return connfd;
  79. }