_socket.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. #include "PikaPlatform_socket.h"
  2. #include "_socket_socket.h"
  3. #if !PIKASCRIPT_VERSION_REQUIRE_MINIMUN(1, 12, 0)
  4. #error "This library requires PikaScript version 1.12.0 or higher"
  5. #endif
  6. void _socket_socket__init(PikaObj* self) {
  7. int family = obj_getInt(self, "family");
  8. int type = obj_getInt(self, "type");
  9. int protocol = obj_getInt(self, "protocol");
  10. int sockfd = 0;
  11. #ifdef _WIN32
  12. pika_platform_init_winsock();
  13. #endif
  14. sockfd = __platform_socket(family, type, protocol);
  15. if (sockfd < 0) {
  16. obj_setErrorCode(self, PIKA_RES_ERR_RUNTIME_ERROR);
  17. obj_setSysOut(self, "socket error");
  18. return;
  19. }
  20. obj_setInt(self, "sockfd", sockfd);
  21. obj_setInt(self, "blocking", 1);
  22. }
  23. void _socket_socket__close(PikaObj* self) {
  24. int sockfd = obj_getInt(self, "sockfd");
  25. __platform_close(sockfd);
  26. #ifdef _WIN32
  27. pika_platform_cleanup_winsock();
  28. #endif
  29. }
  30. void _socket_socket__send(PikaObj* self, Arg* data) {
  31. uint8_t* data_send = NULL;
  32. int len = 0;
  33. if (arg_getType(data) == ARG_TYPE_STRING) {
  34. data_send = (uint8_t*)arg_getStr(data);
  35. len = strGetSize((char*)data_send);
  36. }
  37. if (arg_getType(data) == ARG_TYPE_BYTES) {
  38. data_send = (uint8_t*)arg_getBytes(data);
  39. len = arg_getBytesSize(data);
  40. }
  41. int sockfd = obj_getInt(self, "sockfd");
  42. int ret = 0;
  43. ret = __platform_send(sockfd, data_send, len, 0);
  44. if (ret < 0) {
  45. obj_setErrorCode(self, PIKA_RES_ERR_RUNTIME_ERROR);
  46. obj_setSysOut(self, "send error");
  47. return;
  48. }
  49. }
  50. void _socket_socket__accept(PikaObj* self) {
  51. int sockfd = obj_getInt(self, "sockfd");
  52. int client_sockfd = 0;
  53. struct sockaddr_in client_addr;
  54. socklen_t client_addr_len = sizeof(client_addr);
  55. pika_GIL_EXIT();
  56. client_sockfd = __platform_accept(sockfd, (struct sockaddr*)&client_addr,
  57. &client_addr_len);
  58. pika_GIL_ENTER();
  59. if (client_sockfd < 0) {
  60. obj_setErrorCode(self, PIKA_RES_ERR_RUNTIME_ERROR);
  61. obj_setSysOut(self, "accept error");
  62. return;
  63. }
  64. #ifdef _WIN32
  65. pika_platform_init_winsock();
  66. #endif
  67. obj_setInt(self, "client_sockfd", client_sockfd);
  68. obj_setStr(self, "client_addr", inet_ntoa(client_addr.sin_addr));
  69. }
  70. Arg* _socket_socket__recv(PikaObj* self, int num) {
  71. int sockfd = obj_getInt(self, "sockfd");
  72. int ret = 0;
  73. uint8_t* data_recv = NULL;
  74. Arg* res = arg_newBytes(NULL, num);
  75. data_recv = arg_getBytes(res);
  76. pika_GIL_EXIT();
  77. ret = __platform_recv(sockfd, data_recv, num, 0);
  78. pika_GIL_ENTER();
  79. if (ret <= 0) {
  80. if (obj_getInt(self, "blocking")) {
  81. obj_setErrorCode(self, PIKA_RES_ERR_RUNTIME_ERROR);
  82. if (ret == 0) {
  83. obj_setSysOut(self, "connect closed");
  84. } else {
  85. obj_setSysOut(self, "recv error: %d", ret);
  86. }
  87. arg_deinit(res);
  88. return NULL;
  89. } else {
  90. Arg* res_r = arg_newBytes(NULL, 0);
  91. arg_deinit(res);
  92. return res_r;
  93. }
  94. } else {
  95. if (ret < num) {
  96. uint8_t* res_buff = NULL;
  97. Arg* res_r = arg_newBytes(NULL, ret);
  98. res_buff = arg_getBytes(res_r);
  99. pika_platform_memcpy(res_buff, data_recv, ret);
  100. arg_deinit(res);
  101. return res_r;
  102. }
  103. }
  104. return res;
  105. }
  106. void _socket_socket__listen(PikaObj* self, int num) {
  107. int sockfd = obj_getInt(self, "sockfd");
  108. __platform_listen(sockfd, num);
  109. }
  110. void _socket_socket__connect(PikaObj* self, char* host, int port) {
  111. int sockfd = obj_getInt(self, "sockfd");
  112. struct addrinfo hints, *res;
  113. __platform_memset(&hints, 0, sizeof hints);
  114. hints.ai_family = AF_INET;
  115. if (__platform_getaddrinfo(host, NULL, &hints, &res) != 0) {
  116. obj_setErrorCode(self, PIKA_RES_ERR_RUNTIME_ERROR);
  117. obj_setSysOut(self, "Failed to resolve domain name");
  118. return;
  119. }
  120. struct sockaddr_in* server_addr = (struct sockaddr_in*)res->ai_addr;
  121. server_addr->sin_port = pika_platform_htons(port);
  122. pika_GIL_EXIT();
  123. int err = __platform_connect(sockfd, (struct sockaddr*)server_addr,
  124. sizeof(*server_addr));
  125. pika_GIL_ENTER();
  126. if (0 != err) {
  127. obj_setErrorCode(self, PIKA_RES_ERR_RUNTIME_ERROR);
  128. obj_setSysOut(self, "connect error, err = %d", err);
  129. return;
  130. }
  131. if (obj_getInt(self, "blocking") == 0) {
  132. int flags = pika_platform_fcntl(sockfd, F_GETFL, 0);
  133. if (__platform_fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) == -1) {
  134. obj_setErrorCode(self, PIKA_RES_ERR_RUNTIME_ERROR);
  135. obj_setSysOut(self, "Unable to set socket non blocking");
  136. return;
  137. }
  138. }
  139. __platform_freeaddrinfo(res);
  140. }
  141. void _socket_socket__bind(PikaObj* self, char* host, int port) {
  142. int sockfd = obj_getInt(self, "sockfd");
  143. struct sockaddr_in server_addr;
  144. server_addr.sin_family = AF_INET;
  145. server_addr.sin_port = htons(port);
  146. server_addr.sin_addr.s_addr = inet_addr(host);
  147. int res = __platform_bind(sockfd, (struct sockaddr*)&server_addr,
  148. sizeof(server_addr));
  149. if (res < 0) {
  150. obj_setErrorCode(self, PIKA_RES_ERR_RUNTIME_ERROR);
  151. obj_setSysOut(self, "bind error");
  152. return;
  153. }
  154. }
  155. char* _socket__gethostname(PikaObj* self) {
  156. char hostname_buff[128] = {0};
  157. char* hostname = (char*)hostname_buff;
  158. #ifdef _WIN32
  159. pika_platform_init_winsock();
  160. #endif
  161. pika_platform_gethostname(hostname_buff, 128);
  162. #ifdef _WIN32
  163. pika_platform_cleanup_winsock();
  164. #endif
  165. return obj_cacheStr(self, hostname);
  166. }
  167. char* _socket__gethostbyname(PikaObj* self, char* host) {
  168. struct hostent* host_entry;
  169. char* ip = NULL;
  170. #ifdef _WIN32
  171. pika_platform_init_winsock();
  172. #endif
  173. host_entry = pika_platform_gethostbyname(host);
  174. if (host_entry == NULL) {
  175. obj_setErrorCode(self, PIKA_RES_ERR_RUNTIME_ERROR);
  176. obj_setSysOut(self, "gethostbyname error");
  177. return NULL;
  178. }
  179. ip =
  180. pika_platform_inet_ntoa(*((struct in_addr*)host_entry->h_addr_list[0]));
  181. #ifdef _WIN32
  182. pika_platform_cleanup_winsock();
  183. #endif
  184. return obj_cacheStr(self, ip);
  185. }
  186. void _socket_socket__setblocking(PikaObj* self, int sta) {
  187. obj_setInt(self, "blocking", sta);
  188. }