_socket.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  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. __platform_printf("socket error\n");
  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. __platform_printf("send error\n");
  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. __platform_printf("accept error\n");
  62. return;
  63. }
  64. obj_setInt(self, "client_sockfd", client_sockfd);
  65. obj_setStr(self, "client_addr", inet_ntoa(client_addr.sin_addr));
  66. }
  67. Arg* _socket_socket__recv(PikaObj* self, int num) {
  68. int sockfd = obj_getInt(self, "sockfd");
  69. int ret = 0;
  70. uint8_t* data_recv = NULL;
  71. Arg* res = arg_newBytes(NULL, num);
  72. data_recv = arg_getBytes(res);
  73. pika_GIL_EXIT();
  74. ret = __platform_recv(sockfd, data_recv, num, 0);
  75. pika_GIL_ENTER();
  76. if (ret <= 0) {
  77. if (obj_getInt(self, "blocking")) {
  78. obj_setErrorCode(self, PIKA_RES_ERR_RUNTIME_ERROR);
  79. if (ret == 0) {
  80. // __platform_printf("connect closed\n");
  81. } else {
  82. __platform_printf("recv error: %d\n", ret);
  83. }
  84. arg_deinit(res);
  85. return NULL;
  86. } else {
  87. Arg* res_r = arg_newBytes(NULL, 0);
  88. arg_deinit(res);
  89. return res_r;
  90. }
  91. } else {
  92. if (ret < num) {
  93. uint8_t* res_buff = NULL;
  94. Arg* res_r = arg_newBytes(NULL, ret);
  95. res_buff = arg_getBytes(res_r);
  96. pika_platform_memcpy(res_buff, data_recv, ret);
  97. arg_deinit(res);
  98. return res_r;
  99. }
  100. }
  101. return res;
  102. }
  103. void _socket_socket__listen(PikaObj* self, int num) {
  104. int sockfd = obj_getInt(self, "sockfd");
  105. __platform_listen(sockfd, num);
  106. }
  107. void _socket_socket__connect(PikaObj* self, char* host, int port) {
  108. int sockfd = obj_getInt(self, "sockfd");
  109. struct addrinfo hints, *res;
  110. __platform_memset(&hints, 0, sizeof hints);
  111. hints.ai_family = AF_INET;
  112. if (__platform_getaddrinfo(host, NULL, &hints, &res) != 0) {
  113. obj_setErrorCode(self, PIKA_RES_ERR_RUNTIME_ERROR);
  114. pika_platform_printf("Failed to resolve domain name\n");
  115. return;
  116. }
  117. struct sockaddr_in* server_addr = (struct sockaddr_in*)res->ai_addr;
  118. server_addr->sin_port = pika_platform_htons(port);
  119. pika_GIL_EXIT();
  120. int err = __platform_connect(sockfd, (struct sockaddr*)server_addr,
  121. sizeof(*server_addr));
  122. pika_GIL_ENTER();
  123. if (0 != err) {
  124. obj_setErrorCode(self, PIKA_RES_ERR_RUNTIME_ERROR);
  125. pika_platform_printf("connect error, err = %d\n", err);
  126. return;
  127. }
  128. if (obj_getInt(self, "blocking") == 0) {
  129. int flags = pika_platform_fcntl(sockfd, F_GETFL, 0);
  130. if (__platform_fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) == -1) {
  131. obj_setErrorCode(self, PIKA_RES_ERR_RUNTIME_ERROR);
  132. pika_platform_printf("Unable to set socket non blocking\n");
  133. return;
  134. }
  135. }
  136. __platform_freeaddrinfo(res);
  137. }
  138. void _socket_socket__bind(PikaObj* self, char* host, int port) {
  139. int sockfd = obj_getInt(self, "sockfd");
  140. struct sockaddr_in server_addr;
  141. server_addr.sin_family = AF_INET;
  142. server_addr.sin_port = htons(port);
  143. server_addr.sin_addr.s_addr = inet_addr(host);
  144. int res = __platform_bind(sockfd, (struct sockaddr*)&server_addr,
  145. sizeof(server_addr));
  146. if (res < 0) {
  147. obj_setErrorCode(self, PIKA_RES_ERR_RUNTIME_ERROR);
  148. __platform_printf("bind error\n");
  149. return;
  150. }
  151. }
  152. char* _socket__gethostname(PikaObj* self) {
  153. char hostname_buff[128] = {0};
  154. char* hostname = (char*)hostname_buff;
  155. #ifdef _WIN32
  156. pika_platform_init_winsock();
  157. #endif
  158. pika_platform_gethostname(hostname_buff, 128);
  159. #ifdef _WIN32
  160. pika_platform_cleanup_winsock();
  161. #endif
  162. return obj_cacheStr(self, hostname);
  163. }
  164. char* _socket__gethostbyname(PikaObj* self, char* host) {
  165. struct hostent* host_entry;
  166. char* ip = NULL;
  167. #ifdef _WIN32
  168. pika_platform_init_winsock();
  169. #endif
  170. host_entry = pika_platform_gethostbyname(host);
  171. if (host_entry == NULL) {
  172. obj_setErrorCode(self, PIKA_RES_ERR_RUNTIME_ERROR);
  173. __platform_printf("gethostbyname error\n");
  174. return NULL;
  175. }
  176. ip =
  177. pika_platform_inet_ntoa(*((struct in_addr*)host_entry->h_addr_list[0]));
  178. #ifdef _WIN32
  179. pika_platform_cleanup_winsock();
  180. #endif
  181. return obj_cacheStr(self, ip);
  182. }
  183. void _socket_socket__setblocking(PikaObj* self, int sta) {
  184. obj_setInt(self, "blocking", sta);
  185. }