hsocket.cpp 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  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. return -11;
  27. }
  28. struct sockaddr_in addr;
  29. unsigned int addrlen = sizeof(addr);
  30. memset(&addr, 0, addrlen);
  31. addr.sin_family = AF_INET;
  32. addr.sin_addr.s_addr = htonl(INADDR_ANY);
  33. addr.sin_port = htons(port);
  34. if (bind(listenfd, (struct sockaddr*)&addr, addrlen) < 0) {
  35. perror("bind");
  36. return -20;
  37. }
  38. if (listen(listenfd, SOMAXCONN) < 0) {
  39. perror("listen");
  40. return -30;
  41. }
  42. return listenfd;
  43. }
  44. int Connect(const char* host, int port, int nonblock) {
  45. // gethostbyname -> socket -> nonblocking -> connect
  46. struct sockaddr_in addr;
  47. int addrlen = sizeof(addr);
  48. memset(&addr, 0, addrlen);
  49. addr.sin_family = AF_INET;
  50. addr.sin_addr.s_addr = inet_addr(host);
  51. if (addr.sin_addr.s_addr == INADDR_NONE) {
  52. struct hostent* phe = gethostbyname(host);
  53. if (phe == NULL) return -10;
  54. memcpy(&addr.sin_addr, phe->h_addr, phe->h_length);
  55. }
  56. addr.sin_port = htons(port);
  57. int connfd = socket(AF_INET, SOCK_STREAM, 0);
  58. if (connfd < 0) {
  59. perror("socket");
  60. return -20;
  61. }
  62. if (nonblock) {
  63. nonblocking(connfd);
  64. }
  65. int ret = connect(connfd, (struct sockaddr*)&addr, addrlen);
  66. if (ret != 0 && ret != EINPROGRESS) {
  67. perror("connect");
  68. return -30;
  69. }
  70. return connfd;
  71. }