socket.c
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:7k
源码类别:

数据库系统

开发平台:

Unix_Linux

  1. /* Module:          socket.c
  2.  *
  3.  * Description:     This module contains functions for low level socket
  4.  *                  operations (connecting/reading/writing to the backend)
  5.  *
  6.  * Classes:         SocketClass (Functions prefix: "SOCK_")
  7.  *
  8.  * API functions:   none
  9.  *
  10.  * Comments:        See "notice.txt" for copyright and license information.
  11.  *
  12.  */
  13. #ifdef HAVE_CONFIG_H
  14. #include "config.h"
  15. #endif
  16. #include "socket.h"
  17. #ifndef WIN32
  18. #include <stdlib.h>
  19. #include <string.h> /* for memset */
  20. #endif
  21. extern GLOBAL_VALUES globals;
  22. #ifndef BOOL
  23. #define BOOL int
  24. #endif
  25. #ifndef TRUE
  26. #define TRUE (BOOL)1
  27. #endif
  28. #ifndef FALSE
  29. #define FALSE (BOOL)0
  30. #endif
  31. void
  32. SOCK_clear_error(SocketClass *self)
  33. {
  34. self->errornumber = 0; 
  35. self->errormsg = NULL; 
  36. }
  37. SocketClass * 
  38. SOCK_Constructor()
  39. {
  40. SocketClass *rv;
  41.     rv = (SocketClass *) malloc(sizeof(SocketClass));
  42.     if (rv != NULL) {
  43. rv->socket = (SOCKETFD) -1;
  44. rv->buffer_filled_in = 0;
  45. rv->buffer_filled_out = 0;
  46. rv->buffer_read_in = 0;
  47. rv->buffer_in = (unsigned char *) malloc(globals.socket_buffersize);
  48. if ( ! rv->buffer_in)
  49. return NULL;
  50. rv->buffer_out = (unsigned char *) malloc(globals.socket_buffersize);
  51. if ( ! rv->buffer_out)
  52. return NULL;
  53.         rv->errormsg = NULL;
  54.         rv->errornumber = 0;
  55. rv->reverse = FALSE;
  56.     } 
  57.     return rv;
  58. }
  59. void
  60. SOCK_Destructor(SocketClass *self)
  61. {
  62. if (self->socket != -1) {
  63. if ( ! shutdown(self->socket, 2)) /* no sends or receives */
  64. closesocket(self->socket);
  65. }
  66. if (self->buffer_in)
  67. free(self->buffer_in);
  68. if (self->buffer_out)
  69. free(self->buffer_out);
  70. free(self);
  71. }
  72. char 
  73. SOCK_connect_to(SocketClass *self, unsigned short port, char *hostname)
  74. {
  75. struct hostent *host;
  76. struct sockaddr_in sadr;
  77. unsigned long iaddr;
  78. if (self->socket != -1) {
  79. self->errornumber = SOCKET_ALREADY_CONNECTED;
  80. self->errormsg = "Socket is already connected";
  81. return 0;
  82. }
  83. memset((char *)&sadr, 0, sizeof(sadr));
  84. /* If it is a valid IP address, use it.
  85. Otherwise use hostname lookup. 
  86. */
  87. iaddr = inet_addr(hostname);
  88. if (iaddr == INADDR_NONE) {
  89. host = gethostbyname(hostname);
  90. if (host == NULL) {
  91. self->errornumber = SOCKET_HOST_NOT_FOUND;
  92. self->errormsg = "Could not resolve hostname.";
  93. return 0;
  94. }
  95. memcpy(&(sadr.sin_addr), host->h_addr, host->h_length);
  96. }
  97. else
  98. memcpy(&(sadr.sin_addr), (struct in_addr *) &iaddr, sizeof(iaddr));
  99. sadr.sin_family = AF_INET;
  100. sadr.sin_port = htons(port);
  101. self->socket = socket(AF_INET, SOCK_STREAM, 0);
  102. if (self->socket == -1) {
  103. self->errornumber = SOCKET_COULD_NOT_CREATE_SOCKET;
  104. self->errormsg = "Could not create Socket.";
  105. return 0;
  106. }
  107. if ( connect(self->socket, (struct sockaddr *)&(sadr),
  108. sizeof(sadr))  < 0) {
  109. self->errornumber = SOCKET_COULD_NOT_CONNECT;
  110. self->errormsg = "Could not connect to remote socket.";
  111. closesocket(self->socket);
  112. self->socket = (SOCKETFD) -1;
  113. return 0;
  114. }
  115. return 1;
  116. }
  117. void 
  118. SOCK_get_n_char(SocketClass *self, char *buffer, int len)
  119. {
  120. int lf;
  121. if ( ! buffer) {
  122. self->errornumber = SOCKET_NULLPOINTER_PARAMETER;
  123. self->errormsg = "get_n_char was called with NULL-Pointer";
  124. return;
  125. }
  126. for(lf=0; lf < len; lf++)
  127. buffer[lf] = SOCK_get_next_byte(self);
  128. }
  129. void 
  130. SOCK_put_n_char(SocketClass *self, char *buffer, int len)
  131. {
  132. int lf;
  133. if ( ! buffer) {
  134. self->errornumber = SOCKET_NULLPOINTER_PARAMETER;
  135. self->errormsg = "put_n_char was called with NULL-Pointer";
  136. return;
  137. }
  138. for(lf=0; lf < len; lf++)
  139. SOCK_put_next_byte(self, (unsigned char)buffer[lf]);
  140. }
  141. /*  bufsize must include room for the null terminator 
  142. will read at most bufsize-1 characters + null. 
  143. */
  144. void 
  145. SOCK_get_string(SocketClass *self, char *buffer, int bufsize)
  146. {
  147. register int lf = 0;
  148. for (lf = 0; lf < bufsize; lf++)
  149. if ( ! (buffer[lf] = SOCK_get_next_byte(self)))
  150. return;
  151. buffer[bufsize-1] = '';
  152. }
  153. void 
  154. SOCK_put_string(SocketClass *self, char *string)
  155. {
  156. register int lf;
  157. int len;
  158. len = strlen(string)+1;
  159. for(lf = 0; lf < len; lf++)
  160. SOCK_put_next_byte(self, (unsigned char)string[lf]);
  161. }
  162. int 
  163. SOCK_get_int(SocketClass *self, short len)
  164. {
  165. char buf[4];
  166. switch (len) {
  167. case 2:
  168. SOCK_get_n_char(self, buf, len);
  169. if (self->reverse)
  170. return *((unsigned short *) buf);
  171. else
  172. return ntohs( *((unsigned short *) buf) );
  173. case 4:
  174. SOCK_get_n_char(self, buf, len);
  175. if (self->reverse)
  176. return *((unsigned int *) buf);
  177. else
  178. return ntohl( *((unsigned int *) buf) );
  179. default:
  180. self->errornumber = SOCKET_GET_INT_WRONG_LENGTH;
  181. self->errormsg = "Cannot read ints of that length";
  182. return 0;
  183. }
  184. }
  185. void 
  186. SOCK_put_int(SocketClass *self, int value, short len)
  187. {
  188. unsigned int rv;
  189. switch (len) {
  190. case 2:
  191. rv = self->reverse ? value : htons( (unsigned short) value);
  192. SOCK_put_n_char(self, (char *) &rv, 2);
  193. return;
  194. case 4:
  195. rv = self->reverse ? value : htonl( (unsigned int) value);
  196. SOCK_put_n_char(self, (char *) &rv, 4);
  197. return;
  198. default:
  199. self->errornumber = SOCKET_PUT_INT_WRONG_LENGTH;
  200. self->errormsg = "Cannot write ints of that length";
  201. return;
  202.  }
  203. }
  204. void 
  205. SOCK_flush_output(SocketClass *self)
  206. {
  207. int written;
  208. written = send(self->socket, (char *)self->buffer_out, self->buffer_filled_out, 0);
  209. if (written != self->buffer_filled_out) {
  210. self->errornumber = SOCKET_WRITE_ERROR;
  211. self->errormsg = "Could not flush socket buffer.";
  212. }
  213. self->buffer_filled_out = 0;
  214. }
  215. unsigned char 
  216. SOCK_get_next_byte(SocketClass *self)
  217. {
  218. if (self->buffer_read_in >= self->buffer_filled_in) {
  219. // there are no more bytes left in the buffer ->
  220. // reload the buffer
  221. self->buffer_read_in = 0;
  222. self->buffer_filled_in = recv(self->socket, (char *)self->buffer_in, globals.socket_buffersize, 0);
  223. mylog("read %d, global_socket_buffersize=%dn", self->buffer_filled_in, globals.socket_buffersize);
  224. if (self->buffer_filled_in == -1) {
  225. self->errornumber = SOCKET_READ_ERROR;
  226. self->errormsg = "Error while reading from the socket.";
  227. self->buffer_filled_in = 0;
  228. }
  229. if (self->buffer_filled_in == 0) {
  230. self->errornumber = SOCKET_CLOSED;
  231. self->errormsg = "Socket has been closed.";
  232. self->buffer_filled_in = 0;
  233. }
  234. }
  235. return self->buffer_in[self->buffer_read_in++];
  236. }
  237. void 
  238. SOCK_put_next_byte(SocketClass *self, unsigned char next_byte)
  239. {
  240. int bytes_sent;
  241. self->buffer_out[self->buffer_filled_out++] = next_byte;
  242. if (self->buffer_filled_out == globals.socket_buffersize) {
  243. // buffer is full, so write it out
  244. bytes_sent = send(self->socket, (char *)self->buffer_out, globals.socket_buffersize, 0);
  245. if (bytes_sent != globals.socket_buffersize) {
  246. self->errornumber = SOCKET_WRITE_ERROR;
  247. self->errormsg = "Error while writing to the socket.";
  248. }
  249. self->buffer_filled_out = 0;
  250. }
  251. }