lua-clientsocket.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. #include <lua.h>
  2. #include <lauxlib.h>
  3. #include <string.h>
  4. #include <stdint.h>
  5. #include <pthread.h>
  6. #include <stdlib.h>
  7. #include <netinet/in.h>
  8. #include <sys/types.h>
  9. #include <sys/socket.h>
  10. #include <arpa/inet.h>
  11. #include <unistd.h>
  12. #include <errno.h>
  13. #include <fcntl.h>
  14. #define CACHE_SIZE 0x1000
  15. static int
  16. lconnect(lua_State *L) {
  17. const char * addr = luaL_checkstring(L, 1);
  18. int port = luaL_checkinteger(L, 2);
  19. int fd = socket(AF_INET,SOCK_STREAM,0);
  20. struct sockaddr_in my_addr;
  21. my_addr.sin_addr.s_addr=inet_addr(addr);
  22. my_addr.sin_family=AF_INET;
  23. my_addr.sin_port=htons(port);
  24. int r = connect(fd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr_in));
  25. if (r == -1) {
  26. return luaL_error(L, "Connect %s %d failed", addr, port);
  27. }
  28. int flag = fcntl(fd, F_GETFL, 0);
  29. fcntl(fd, F_SETFL, flag | O_NONBLOCK);
  30. lua_pushinteger(L, fd);
  31. return 1;
  32. }
  33. static int
  34. lclose(lua_State *L) {
  35. int fd = luaL_checkinteger(L, 1);
  36. close(fd);
  37. return 0;
  38. }
  39. static void
  40. block_send(lua_State *L, int fd, const char * buffer, int sz) {
  41. while(sz > 0) {
  42. int r = send(fd, buffer, sz, 0);
  43. if (r < 0) {
  44. if (errno == EAGAIN || errno == EINTR)
  45. continue;
  46. luaL_error(L, "socket error: %s", strerror(errno));
  47. }
  48. buffer += r;
  49. sz -= r;
  50. }
  51. }
  52. /*
  53. integer fd
  54. string message
  55. */
  56. static int
  57. lsend(lua_State *L) {
  58. size_t sz = 0;
  59. int fd = luaL_checkinteger(L,1);
  60. const char * msg = luaL_checklstring(L, 2, &sz);
  61. block_send(L, fd, msg, (int)sz);
  62. return 0;
  63. }
  64. /*
  65. intger fd
  66. string last
  67. table result
  68. return
  69. boolean (true: data, false: block, nil: close)
  70. string last
  71. */
  72. struct socket_buffer {
  73. void * buffer;
  74. int sz;
  75. };
  76. static int
  77. lrecv(lua_State *L) {
  78. int fd = luaL_checkinteger(L,1);
  79. char buffer[CACHE_SIZE];
  80. int r = recv(fd, buffer, CACHE_SIZE, 0);
  81. if (r == 0) {
  82. lua_pushliteral(L, "");
  83. // close
  84. return 1;
  85. }
  86. if (r < 0) {
  87. if (errno == EAGAIN || errno == EINTR) {
  88. return 0;
  89. }
  90. luaL_error(L, "socket error: %s", strerror(errno));
  91. }
  92. lua_pushlstring(L, buffer, r);
  93. return 1;
  94. }
  95. static int
  96. lusleep(lua_State *L) {
  97. int n = luaL_checknumber(L, 1);
  98. usleep(n);
  99. return 0;
  100. }
  101. int
  102. luaopen_clientsocket(lua_State *L) {
  103. luaL_checkversion(L);
  104. luaL_Reg l[] = {
  105. { "connect", lconnect },
  106. { "recv", lrecv },
  107. { "send", lsend },
  108. { "close", lclose },
  109. { "usleep", lusleep },
  110. { NULL, NULL },
  111. };
  112. luaL_newlib(L, l);
  113. return 1;
  114. }