socket_io.cpp
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:6k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2003 MySQL AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. #include <ndb_global.h>
  14. #include <NdbTCP.h>
  15. #include <socket_io.h>
  16. #include <NdbOut.hpp>
  17. extern "C"
  18. int
  19. read_socket(NDB_SOCKET_TYPE socket, int timeout_millis, 
  20.     char * buf, int buflen){
  21.   if(buflen < 1)
  22.     return 0;
  23.   
  24.   fd_set readset;
  25.   FD_ZERO(&readset);
  26.   FD_SET(socket, &readset);
  27.   
  28.   struct timeval timeout;
  29.   timeout.tv_sec  = (timeout_millis / 1000);
  30.   timeout.tv_usec = (timeout_millis % 1000) * 1000;
  31.   const int selectRes = select(socket + 1, &readset, 0, 0, &timeout);
  32.   if(selectRes == 0)
  33.     return 0;
  34.   
  35.   if(selectRes == -1){
  36.     return -1;
  37.   }
  38.   return recv(socket, &buf[0], buflen, 0);
  39. }
  40. extern "C"
  41. int
  42. readln_socket(NDB_SOCKET_TYPE socket, int timeout_millis, 
  43.       char * buf, int buflen){
  44.   if(buflen <= 1)
  45.     return 0;
  46.   fd_set readset;
  47.   FD_ZERO(&readset);
  48.   FD_SET(socket, &readset);
  49.   
  50.   struct timeval timeout;
  51.   timeout.tv_sec  = (timeout_millis / 1000);
  52.   timeout.tv_usec = (timeout_millis % 1000) * 1000;
  53.   const int selectRes = select(socket + 1, &readset, 0, 0, &timeout);
  54.   if(selectRes == 0)
  55.     return 0;
  56.   
  57.   if(selectRes == -1){
  58.     return -1;
  59.   }
  60.   
  61.   int pos = 0; buf[pos] = 0;
  62.   while(true){
  63.     const int t = recv(socket, &buf[pos], 1, 0);
  64.     if(t != 1){
  65.       return -1;
  66.     }
  67.     if(buf[pos] == 'n'){
  68.       buf[pos] = 0;
  69.       if(pos > 0 && buf[pos-1] == 'r'){
  70. pos--;
  71. buf[pos] = 0;
  72.       }
  73.       return pos;
  74.     }
  75.     pos++;
  76.     if(pos == (buflen - 1)){
  77.       buf[pos] = 0;
  78.       return buflen;
  79.     }
  80.     
  81.     FD_ZERO(&readset);
  82.     FD_SET(socket, &readset);
  83.     timeout.tv_sec  = (timeout_millis / 1000);
  84.     timeout.tv_usec = (timeout_millis % 1000) * 1000;
  85.     const int selectRes = select(socket + 1, &readset, 0, 0, &timeout);
  86.     if(selectRes != 1){
  87.       return -1;
  88.     }
  89.   }
  90. }
  91. extern "C"
  92. int
  93. write_socket(NDB_SOCKET_TYPE socket, int timeout_millis, 
  94.      const char buf[], int len){
  95.   fd_set writeset;
  96.   FD_ZERO(&writeset);
  97.   FD_SET(socket, &writeset);
  98.   struct timeval timeout;
  99.   timeout.tv_sec  = (timeout_millis / 1000);
  100.   timeout.tv_usec = (timeout_millis % 1000) * 1000;
  101.   const int selectRes = select(socket + 1, 0, &writeset, 0, &timeout);
  102.   if(selectRes != 1){
  103.     return -1;
  104.   }
  105.   const char * tmp = &buf[0];
  106.   while(len > 0){
  107.     const int w = send(socket, tmp, len, 0);
  108.     if(w == -1){
  109.       return -1;
  110.     }
  111.     len -= w;
  112.     tmp += w;
  113.     
  114.     if(len == 0)
  115.       break;
  116.     
  117.     FD_ZERO(&writeset);
  118.     FD_SET(socket, &writeset);
  119.     timeout.tv_sec  = 1;
  120.     timeout.tv_usec = 0;
  121.     const int selectRes = select(socket + 1, 0, &writeset, 0, &timeout);
  122.     if(selectRes != 1){
  123.       return -1;
  124.     }
  125.   }
  126.   
  127.   return 0;
  128. }
  129. extern "C"
  130. int
  131. print_socket(NDB_SOCKET_TYPE socket, int timeout_millis, 
  132.      const char * fmt, ...){
  133.   va_list ap;
  134.   va_start(ap, fmt);
  135.   int ret = vprint_socket(socket, timeout_millis, fmt, ap);
  136.   va_end(ap);
  137.   return ret;
  138. }
  139. extern "C"
  140. int
  141. println_socket(NDB_SOCKET_TYPE socket, int timeout_millis, 
  142.        const char * fmt, ...){
  143.   va_list ap;
  144.   va_start(ap, fmt);
  145.   int ret = vprintln_socket(socket, timeout_millis, fmt, ap);
  146.   va_end(ap);
  147.   return ret;
  148. }
  149. extern "C"
  150. int
  151. vprint_socket(NDB_SOCKET_TYPE socket, int timeout_millis, 
  152.       const char * fmt, va_list ap){
  153.   char buf[1000];
  154.   char *buf2 = buf;
  155.   size_t size;
  156.   if (fmt != 0 && fmt[0] != 0) {
  157.     size = BaseString::vsnprintf(buf, sizeof(buf), fmt, ap);
  158.     /* Check if the output was truncated */
  159.     if(size > sizeof(buf)) {
  160.       buf2 = (char *)malloc(size);
  161.       if(buf2 == NULL)
  162. return -1;
  163.       BaseString::vsnprintf(buf2, size, fmt, ap);
  164.     }
  165.   } else
  166.     return 0;
  167.   int ret = write_socket(socket, timeout_millis, buf2, size);
  168.   if(buf2 != buf)
  169.     free(buf2);
  170.   return ret;
  171. }
  172. extern "C"
  173. int
  174. vprintln_socket(NDB_SOCKET_TYPE socket, int timeout_millis, 
  175. const char * fmt, va_list ap){
  176.   char buf[1000];
  177.   char *buf2 = buf;
  178.   size_t size;
  179.   if (fmt != 0 && fmt[0] != 0) {
  180.     size = BaseString::vsnprintf(buf, sizeof(buf), fmt, ap)+1;// extra byte for '/n'
  181.     /* Check if the output was truncated */
  182.     if(size > sizeof(buf)) {
  183.       buf2 = (char *)malloc(size);
  184.       if(buf2 == NULL)
  185. return -1;
  186.       BaseString::vsnprintf(buf2, size, fmt, ap);
  187.     }
  188.   } else {
  189.     size = 1;
  190.   }
  191.   buf2[size-1]='n';
  192.   int ret = write_socket(socket, timeout_millis, buf2, size);
  193.   if(buf2 != buf)
  194.     free(buf2);
  195.   return ret;
  196. }
  197. #ifdef NDB_WIN32
  198. class INIT_WINSOCK2
  199. {
  200. public:
  201.     INIT_WINSOCK2(void);
  202.     ~INIT_WINSOCK2(void);
  203. private:
  204.     bool m_bAcceptable;
  205. };
  206. INIT_WINSOCK2 g_init_winsock2;
  207. INIT_WINSOCK2::INIT_WINSOCK2(void)
  208. : m_bAcceptable(false)
  209. {
  210.     WORD wVersionRequested;
  211.     WSADATA wsaData;
  212.     int err;
  213.     
  214.     wVersionRequested = MAKEWORD( 2, 2 );
  215.     
  216.     err = WSAStartup( wVersionRequested, &wsaData );
  217.     if ( err != 0 ) {
  218.         /* Tell the user that we could not find a usable */
  219.         /* WinSock DLL.                                  */
  220.         m_bAcceptable = false;
  221.     }
  222.     
  223.     /* Confirm that the WinSock DLL supports 2.2.*/
  224.     /* Note that if the DLL supports versions greater    */
  225.     /* than 2.2 in addition to 2.2, it will still return */
  226.     /* 2.2 in wVersion since that is the version we      */
  227.     /* requested.                                        */
  228.     
  229.     if ( LOBYTE( wsaData.wVersion ) != 2 ||
  230.         HIBYTE( wsaData.wVersion ) != 2 ) {
  231.         /* Tell the user that we could not find a usable */
  232.         /* WinSock DLL.                                  */
  233.         WSACleanup( );
  234.         m_bAcceptable = false; 
  235.     }
  236.     
  237.     /* The WinSock DLL is acceptable. Proceed. */
  238.     m_bAcceptable = true;
  239. }
  240. INIT_WINSOCK2::~INIT_WINSOCK2(void)
  241. {
  242.     if(m_bAcceptable)
  243.     {
  244.         m_bAcceptable = false;
  245.         WSACleanup();
  246.     }
  247. }
  248. #endif