/fbus/fbus_stream_socket.c

http://ftk.googlecode.com/ · C · 186 lines · 119 code · 38 blank · 29 comment · 11 complexity · 1b0d901bd827d33ed272c829df035063 MD5 · raw file

  1. /*
  2. * File: fbus_stream_socket.c
  3. * Author: Li XianJing <xianjimli@hotmail.com>
  4. * Brief: socket implemented stream interface.
  5. *
  6. * Copyright (c) 2009 - 2010 Li XianJing <xianjimli@hotmail.com>
  7. *
  8. * Licensed under the Academic Free License version 2.1
  9. *
  10. * This program is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License as published by
  12. * the Free Software Foundation; either version 2 of the License, or
  13. * (at your option) any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with this program; if not, write to the Free Software
  22. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  23. */
  24. /*
  25. * History:
  26. * ================================================================
  27. * 2010-07-25 Li XianJing <xianjimli@hotmail.com> created
  28. *
  29. */
  30. #include <netdb.h>
  31. #include <sys/types.h>
  32. #include <sys/socket.h>
  33. #include <netinet/tcp.h>
  34. #include "ftk_allocator.h"
  35. #include "fbus_stream_socket.h"
  36. #ifdef WIN32
  37. #define ftk_close_socket closesocket
  38. #else
  39. #define ftk_close_socket close
  40. #endif
  41. typedef struct _PrivInfo
  42. {
  43. int sock_no;
  44. }PrivInfo;
  45. static int fbus_stream_socket_read(FBusStream* thiz, char* buffer, size_t len)
  46. {
  47. DECL_PRIV(thiz, priv);
  48. return recv(priv->sock_no, buffer, len, 0);
  49. }
  50. static int fbus_stream_socket_write(FBusStream* thiz, const char* buffer, size_t len)
  51. {
  52. DECL_PRIV(thiz, priv);
  53. return send(priv->sock_no, buffer, len, 0);
  54. }
  55. static int fbus_stream_socket_get_fd(FBusStream* thiz)
  56. {
  57. DECL_PRIV(thiz, priv);
  58. return priv->sock_no;
  59. }
  60. static void fbus_stream_socket_destroy(FBusStream* thiz)
  61. {
  62. if(thiz != NULL)
  63. {
  64. DECL_PRIV(thiz, priv);
  65. ftk_close_socket(priv->sock_no);
  66. FTK_FREE(thiz);
  67. }
  68. return;
  69. }
  70. FBusStream* fbus_stream_socket_create(int sock_no)
  71. {
  72. FBusStream* thiz = NULL;
  73. return_val_if_fail(sock_no > 0, NULL);
  74. thiz = FTK_ZALLOC(sizeof(FBusStream) + sizeof(PrivInfo));
  75. if(thiz != NULL)
  76. {
  77. int opt_value = 1;
  78. DECL_PRIV(thiz, priv);
  79. thiz->read = fbus_stream_socket_read;
  80. thiz->write = fbus_stream_socket_write;
  81. thiz->get_fd = fbus_stream_socket_get_fd;
  82. thiz->destroy = fbus_stream_socket_destroy;
  83. setsockopt(sock_no, IPPROTO_TCP, TCP_NODELAY, &opt_value, sizeof(opt_value));
  84. setsockopt(sock_no, SOL_SOCKET, SO_KEEPALIVE, &opt_value, sizeof(opt_value));
  85. priv->sock_no = sock_no;
  86. }
  87. return thiz;
  88. }
  89. FBusStream* fbus_stream_socket_connect(const char* host, int port)
  90. {
  91. int sock_no = -1;
  92. struct sockaddr_in addr;
  93. struct hostent* hostent_ptr = NULL;
  94. return_val_if_fail(host != NULL && port > 0, NULL);
  95. hostent_ptr = gethostbyname(host);
  96. return_val_if_fail(hostent_ptr != NULL, NULL);
  97. addr.sin_family = PF_INET;
  98. addr.sin_port = htons((unsigned short)port);
  99. addr.sin_addr.s_addr = *(unsigned long*)(hostent_ptr->h_addr_list[0]);
  100. sock_no = socket(PF_INET, SOCK_STREAM, 0);
  101. if(connect(sock_no, (struct sockaddr*)&(addr), sizeof(addr)) == 0)
  102. {
  103. return fbus_stream_socket_create(sock_no);
  104. }
  105. else
  106. {
  107. perror("connect");
  108. return NULL;
  109. }
  110. }
  111. int fbus_stream_listen(int port)
  112. {
  113. int opt_value = 1;
  114. struct sockaddr_in addr_server = {0};
  115. int sock_listen = socket(PF_INET, SOCK_STREAM, 0);
  116. return_val_if_fail(sock_listen > 0, -1);
  117. addr_server.sin_family = PF_INET;
  118. addr_server.sin_port = htons(port);
  119. addr_server.sin_addr.s_addr = INADDR_ANY;
  120. setsockopt(sock_listen, SOL_SOCKET, SO_REUSEADDR, &opt_value, sizeof(opt_value));
  121. if(bind(sock_listen, (struct sockaddr*)&addr_server, sizeof(addr_server)) < 0)
  122. {
  123. perror("bind");
  124. ftk_close_socket(sock_listen);
  125. return -1;
  126. }
  127. if(listen(sock_listen, 5) < 0)
  128. {
  129. perror("listen");
  130. ftk_close_socket(sock_listen);
  131. return -1;
  132. }
  133. return sock_listen;
  134. }
  135. FBusStream* fbus_socket_accept(int sock_no)
  136. {
  137. int addrlen = 0;
  138. int sock_client = 0;
  139. struct sockaddr_in addr_client = {0};
  140. memset(&addr_client, 0x00, sizeof(addr_client));
  141. sock_client = accept(sock_no, (struct sockaddr*)&addr_client, (socklen_t*)&addrlen);
  142. return_val_if_fail(sock_client > 0, NULL);
  143. return fbus_stream_socket_create(sock_client);
  144. }
  145. Ret ftk_socket_close(int sock_no)
  146. {
  147. return ftk_close_socket(sock_no);
  148. }