hsocket.cpp 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  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. unsigned int 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. int 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. if (ret < 0 && sockerrno != EINPROGRESS) {
  70. perror("connect");
  71. closesocket(connfd);
  72. return -30;
  73. }
  74. return connfd;
  75. }