Ignore:
Timestamp:
2001-04-05T17:08:52+12:00 (23 years ago)
Author:
sjboddie
Message:

Had a bit of a tidy up in the fnord webserver code. The main change of note
was the removal of our reliance on the MAX_URL_SIZE constant. URLs and post
data of any length should now work.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/gsdl/src/w32server/netio.cpp

    r1203 r2286  
    1 /*
    2 Copyright (C) 1996
    3 
    4 This program is free software; you can redistribute it and/or modify
    5 it under the terms of the GNU General Public License as published by
    6 the Free Software Foundation; either version 2 of the License, or
    7 (at your option) any later version.
    8 
    9 This program is distributed in the hope that it will be useful,
    10 but WITHOUT ANY WARRANTY; without even the implied warranty of
    11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12 GNU General Public License for more details.
    13 
    14 You should have received a copy of the GNU General Public License
    15 along with this program; if not, write to the Free Software
    16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    17 
    18 The author can be contacted via Email at [email protected]
    19 */
     1/**********************************************************************
     2 *
     3 * netio.cpp
     4 * Copyright (C) 1996
     5 *
     6 * A component of the fnord webserver written by [email protected].
     7 *
     8 * Altered for use with the Greenstone digital library software by the
     9 * New Zealand Digital Library Project at the University of Waikato,
     10 * New Zealand.
     11 *
     12 * This program is free software; you can redistribute it and/or modify
     13 * it under the terms of the GNU General Public License as published by
     14 * the Free Software Foundation; either version 2 of the License, or
     15 * (at your option) any later version.
     16 *
     17 * This program is distributed in the hope that it will be useful,
     18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     20 * GNU General Public License for more details.
     21 *
     22 * You should have received a copy of the GNU General Public License
     23 * along with this program; if not, write to the Free Software
     24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     25 *
     26 *********************************************************************/
    2027
    2128#include <windows.h>
     
    4148int dns_msg_error = 0;
    4249
    43 
    4450DWORD LocalIPNumber;
    4551char LocalName[MAXHOSTNAME];
    4652
    47 
    4853//Private Function Declarations
    4954DWORD GetHostID();
    50 
    5155
    5256// returns 0 on success,
    5357// WSASYSNOTREADY, WSAVERNOTSUPPORTED, or WSAEINVAL on failure
    5458int InitNetIO() {
    55     WSADATA Data;
    56 
    57     // Load Winsock
    58     int err = d_WSAStartup(MAKEWORD(1, 1), &Data);
    59 
    60     // get local IP number
    61     if (err == 0) LocalIPNumber = GetHostID();
    62     else LocalIPNumber = INADDR_ANY;
    63 
    64     // set the Local Name to "" for now
    65     LocalName[0] = 0;
     59  WSADATA Data;
     60 
     61  // Load Winsock
     62  int err = d_WSAStartup(MAKEWORD(1, 1), &Data);
     63 
     64  // get local IP number
     65  if (err == 0) LocalIPNumber = GetHostID();
     66  else LocalIPNumber = INADDR_ANY;
     67 
     68  // set the Local Name to "" for now
     69  LocalName[0] = 0;
     70 
     71  return err;
     72}
     73
     74
     75void CleanUpNetIO() {
     76  //Experimental, heard this will better clean up, especialy if a call is
     77  //blocking....
     78  d_WSAUnhookBlockingHook();
     79
     80  //Clean up Winsock
     81  d_WSACleanup() == SOCKET_ERROR;
     82}
     83
     84
     85void ResetNetIO() {
     86  //Figure out the local name on first querry, set to "" until then...
     87  LocalName[0] = 0;
     88}
     89
     90
     91DWORD GetLocalIP() {
     92  return LocalIPNumber;
     93}
     94
     95long __stdcall DNSWindowProc(HWND hWnd,UINT wMsg, WPARAM wParam, LPARAM lParam) {
     96  if (wMsg == HTTP_DNS_MSG) {
     97    dns_msg_received = 1;
     98    dns_msg_error = WSAGETASYNCERROR(lParam);
     99    return 0;
     100  }
     101 
     102  return DefWindowProc(hWnd, wMsg, wParam, lParam);
     103}
     104
     105char *GetLocalName(HINSTANCE hInstance) {
     106  // static in case it is written to after the function has finished
     107  // (I did not error checking on WSACancelAsyncRequest)
     108  static char buf[MAXGETHOSTSTRUCT];
    66109   
    67     return err;
    68 }
    69 
    70 
    71 void CleanUpNetIO() {
    72     //Experimental, heard this will better clean up, especialy if a call is
    73     //blocking....
    74     d_WSAUnhookBlockingHook();
    75 
    76     //Clean up Winsock
    77     d_WSACleanup() == SOCKET_ERROR;
    78 }
    79 
    80 
    81 void ResetNetIO() {
    82     //Figure out the local name on first querry, set to "" until then...
    83     LocalName[0] = 0;
    84 }
    85 
    86 
    87 DWORD GetLocalIP() {
    88     return LocalIPNumber;
    89 }
    90 
    91 
    92 
    93 
    94 
    95 long __stdcall DNSWindowProc(HWND hWnd,UINT wMsg, WPARAM wParam, LPARAM lParam) {
    96     if (wMsg == HTTP_DNS_MSG) {
    97         dns_msg_received = 1;
    98         dns_msg_error = WSAGETASYNCERROR(lParam);
    99         return 0;
     110  if (LocalName[0] == 0) {
     111    hostent *DNSResult = NULL;
     112    in_addr LocalInAddr;
     113   
     114    // if we failed to get the local IP number
     115    // use the loop-back device
     116    if (LocalIPNumber == INADDR_ANY) {
     117      strcpy(LocalName, "127.0.0.1"); // loop-back device
     118      return LocalName;
     119    }
     120   
     121    //Convert the number to an in_addr struct
     122    LocalInAddr.s_addr = LocalIPNumber;
     123   
     124    // if we fail to find the domain name we will
     125    // still want the IP address
     126    strcpy(LocalName, d_inet_ntoa(LocalInAddr));
     127   
     128    // make sure they actually passed in an instance handle
     129    if (hInstance == NULL) return LocalName;
     130   
     131    // do a async domain name lookup so that we
     132    // can control the timeout
     133   
     134    // create a window class and window to handle the async messages
     135    WNDCLASS wc; HWND hwndDNS;
     136   
     137    wc.style = 0;
     138    wc.lpfnWndProc = DNSWindowProc;
     139    wc.cbClsExtra = 0;
     140    wc.cbWndExtra = 0;
     141    wc.hInstance = hInstance;
     142    wc.hIcon = NULL;
     143    wc.hCursor = NULL;
     144    wc.hbrBackground = NULL;
     145    wc.lpszMenuName = NULL;
     146    wc.lpszClassName = "GSDL DNS Window";
     147    if (!RegisterClass(&wc)) return LocalName;
     148   
     149    hwndDNS = CreateWindow("GSDL DNS Window", "",
     150               WS_OVERLAPPEDWINDOW, 0, 0, 100, 100,
     151               NULL, NULL, hInstance, NULL);
     152    if (!hwndDNS) return LocalName;
     153   
     154    // process all messages currently on the queue
     155    MSG Message;
     156    while (PeekMessage(&Message, NULL, 0, 0, PM_REMOVE)) {
     157      TranslateMessage(&Message); /* translate keyboard messages */
     158      DispatchMessage(&Message);  /* return control to Windows NT */
     159    }
     160   
     161    //Do a async DNS lookup on the IP number
     162    dns_msg_received = 0;
     163    dns_msg_error = 0;
     164    HANDLE asyncGetHostReq = d_WSAAsyncGetHostByAddr(
     165                             hwndDNS, HTTP_DNS_MSG, (char *)&(LocalInAddr),
     166                             4, PF_INET, buf, MAXGETHOSTSTRUCT);
     167   
     168    if (asyncGetHostReq != NULL) {
     169      // wait 5 seconds for the request to complete
     170      int now = GetTickCount();
     171      while ((DiffTickCounts(now, GetTickCount()) < 5000) && !dns_msg_received) {
     172    if (PeekMessage(&Message, NULL, 0, 0, PM_REMOVE)) {
     173      TranslateMessage(&Message); /* translate keyboard messages */
     174      DispatchMessage(&Message);  /* return control to Windows NT */
     175    } else {
     176      Sleep(1);
    100177    }
    101 
    102     return DefWindowProc(hWnd, wMsg, wParam, lParam);
    103 }
    104 
    105 char *GetLocalName(HINSTANCE hInstance) {
    106     // static in case it is written to after the function has finished
    107     // (I did not error checking on WSACancelAsyncRequest)
    108     static char buf[MAXGETHOSTSTRUCT];
    109 
    110    
    111     if (LocalName[0] == 0) {
    112         hostent *DNSResult = NULL;
    113         in_addr LocalInAddr;
    114 
    115         // if we failed to get the local IP number
    116         // use the loop-back device
    117         if (LocalIPNumber == INADDR_ANY) {
    118             strcpy(LocalName, "127.0.0.1"); // loop-back device
    119             return LocalName;
    120         }
    121 
    122         //Convert the number to an in_addr struct
    123         LocalInAddr.s_addr = LocalIPNumber;
    124 
    125         // if we fail to find the domain name we will
    126         // still want the IP address
    127         strcpy(LocalName, d_inet_ntoa(LocalInAddr));
    128 
    129 
    130         // make sure they actually passed in an instance handle
    131         if (hInstance == NULL) return LocalName;
    132 
    133         // do a async domain name lookup so that we
    134         // can control the timeout
    135 
    136         // create a window class and window to handle the async messages
    137         WNDCLASS wc; HWND hwndDNS;
    138    
    139         wc.style = 0;
    140         wc.lpfnWndProc = DNSWindowProc;
    141         wc.cbClsExtra = 0;
    142         wc.cbWndExtra = 0;
    143         wc.hInstance = hInstance;
    144         wc.hIcon = NULL;
    145         wc.hCursor = NULL;
    146         wc.hbrBackground = NULL;
    147         wc.lpszMenuName = NULL;
    148         wc.lpszClassName = "GSDL DNS Window";
    149         if (!RegisterClass(&wc)) return LocalName;
    150 
    151         hwndDNS = CreateWindow("GSDL DNS Window", "",
    152             WS_OVERLAPPEDWINDOW, 0, 0, 100, 100,
    153             NULL, NULL, hInstance, NULL);
    154         if (!hwndDNS) return LocalName;
    155 
    156         // process all messages currently on the queue
    157         MSG Message;
    158         while (PeekMessage(&Message, NULL, 0, 0, PM_REMOVE)) {
    159             TranslateMessage(&Message); /* translate keyboard messages */
    160             DispatchMessage(&Message);  /* return control to Windows NT */
    161         }
    162 
    163         //Do a async DNS lookup on the IP number
    164         dns_msg_received = 0;
    165         dns_msg_error = 0;
    166         HANDLE asyncGetHostReq = d_WSAAsyncGetHostByAddr(
    167             hwndDNS, HTTP_DNS_MSG, (char *)&(LocalInAddr),
    168             4, PF_INET, buf, MAXGETHOSTSTRUCT);
    169    
    170         if (asyncGetHostReq != NULL) {
    171             // wait 5 seconds for the request to complete
    172             int now = GetTickCount();
    173             while ((DiffTickCounts(now, GetTickCount()) < 5000) && !dns_msg_received) {
    174                 if (PeekMessage(&Message, NULL, 0, 0, PM_REMOVE)) {
    175                     TranslateMessage(&Message); /* translate keyboard messages */
    176                     DispatchMessage(&Message);  /* return control to Windows NT */
    177                 } else {
    178                     Sleep(1);
    179                 }
    180             }
    181             if (!dns_msg_received)
    182                 d_WSACancelAsyncRequest(asyncGetHostReq);
    183         }
    184 
    185         DestroyWindow(hwndDNS);
    186 
    187         if (dns_msg_received && (dns_msg_error == 0)) {
    188             //Worked, use the primary name
    189             strcpy(LocalName, ((hostent *)(buf))->h_name);
    190             //Convert it to lower case for cosmedic reasons
    191             CharLower(LocalName);
    192         }
    193     }
    194     return LocalName;
     178      }
     179      if (!dns_msg_received)
     180    d_WSACancelAsyncRequest(asyncGetHostReq);
     181    }
     182   
     183    DestroyWindow(hwndDNS);
     184   
     185    if (dns_msg_received && (dns_msg_error == 0)) {
     186      //Worked, use the primary name
     187      strcpy(LocalName, ((hostent *)(buf))->h_name);
     188      //Convert it to lower case for cosmedic reasons
     189      CharLower(LocalName);
     190    }
     191  }
     192  return LocalName;
    195193}
    196194
     
    203201
    204202#define MAXBINDCOUNT 4096
    205 int CreateListeningSocket(int &PortNum, HWND MsgWindow, WORD SocketMsg, SOCKET &ServerSocket) {
    206     int err = 0;
    207     SOCKADDR_IN ServerSockAddr;
    208     int bind_port, bind_count;
    209 
    210     //Create the Server Socket
    211     ServerSocket = d_socket(AF_INET, SOCK_STREAM, 0);
    212     if (ServerSocket == INVALID_SOCKET) return d_WSAGetLastError();
    213 
    214     bind_port = PortNum;
    215     for (bind_count=0; bind_count < MAXBINDCOUNT; bind_count++) {
    216         // Set up the Server Socket Address
    217         memset(&ServerSockAddr, 0, sizeof(ServerSockAddr)); //Needed?
    218         ServerSockAddr.sin_port = d_htons( (WORD) bind_port);
    219         ServerSockAddr.sin_family = AF_INET;
    220         ServerSockAddr.sin_addr.s_addr = d_htonl(INADDR_ANY);
    221 
    222         // Try to bind the socket with the address
    223         if (d_bind(ServerSocket, (LPSOCKADDR) &ServerSockAddr,
    224                 sizeof(ServerSockAddr)) != SOCKET_ERROR) {
    225             PortNum = bind_port;
    226             break;
    227         }
    228 
    229         // make sure it failed to bind because it was
    230         // already bound
    231         err = d_WSAGetLastError ();
    232         if (err != WSAEADDRINUSE) return err;
    233 
    234         // Or choose another port number to try
    235         if (bind_port == 80) bind_port = IPPORT_RESERVED+1;
    236         else if (bind_count == 0) bind_port = 80;
    237         else bind_port++;
     203int CreateListeningSocket(int &PortNum, HWND MsgWindow,
     204              WORD SocketMsg, SOCKET &ServerSocket) {
     205  int err = 0;
     206  SOCKADDR_IN ServerSockAddr;
     207  int bind_port, bind_count;
     208 
     209  //Create the Server Socket
     210  ServerSocket = d_socket(AF_INET, SOCK_STREAM, 0);
     211  if (ServerSocket == INVALID_SOCKET) return d_WSAGetLastError();
     212 
     213  bind_port = PortNum;
     214  for (bind_count=0; bind_count < MAXBINDCOUNT; bind_count++) {
     215    // Set up the Server Socket Address
     216    memset(&ServerSockAddr, 0, sizeof(ServerSockAddr)); //Needed?
     217    ServerSockAddr.sin_port = d_htons( (WORD) bind_port);
     218    ServerSockAddr.sin_family = AF_INET;
     219    ServerSockAddr.sin_addr.s_addr = d_htonl(INADDR_ANY);
     220   
     221    // Try to bind the socket with the address
     222    if (d_bind(ServerSocket, (LPSOCKADDR) &ServerSockAddr,
     223           sizeof(ServerSockAddr)) != SOCKET_ERROR) {
     224      PortNum = bind_port;
     225      break;
     226    }
     227   
     228    // make sure it failed to bind because it was
     229    // already bound
     230    err = d_WSAGetLastError ();
     231    if (err != WSAEADDRINUSE) return err;
     232   
     233    // Or choose another port number to try
     234    if (bind_port == 80) bind_port = IPPORT_RESERVED+1;
     235    else if (bind_count == 0) bind_port = 80;
     236    else bind_port++;
     237  }
     238 
     239  // return an error in we couldn't find a valid port
     240  if (bind_count == MAXBINDCOUNT) return WSAEADDRINUSE;
     241 
     242  // Start listening for connections
     243  if (d_listen(ServerSocket, SOMAXCONN) == SOCKET_ERROR)
     244    return d_WSAGetLastError ();   
     245 
     246  // Set up event for new connections
     247  if (d_WSAAsyncSelect(ServerSocket, MsgWindow, SocketMsg, FD_ACCEPT) == SOCKET_ERROR)
     248    return d_WSAGetLastError ();
     249 
     250  return 0;
     251}
     252
     253
     254int AnswerListeningSocket(SOCKET ServerSocket, SOCKET &ClientSocket,
     255              SOCKADDR_IN &ClientSockAddr, int AddrLen) {
     256  if (d_WSAIsBlocking()) {
     257    log_message("rejected connect due blocking\n");
     258    return -1;
     259  }
     260 
     261  ClientSocket = d_accept(ServerSocket, (LPSOCKADDR) &ClientSockAddr, &AddrLen);
     262  if (ClientSocket == INVALID_SOCKET) {
     263    log_message("accept failed - connection lost\n");
     264    return -1;
     265  }
     266 
     267  log_message("accept success - connection made\n");
     268  return 0;
     269}
     270
     271void DestroyListeningSocket(SOCKET &ServerSocket, HWND MsgWindow) {
     272  //Remove any message notification
     273  d_WSAAsyncSelect(ServerSocket, MsgWindow, 0, 0);
     274 
     275  //Close the socket
     276  CloseSocket(ServerSocket);
     277}
     278
     279void CloseSocket(SOCKET &TargetSocket) {
     280  if (TargetSocket != INVALID_SOCKET) {
     281    //Since we're closing the socket, there's not much I can do about errors
     282    //now so I'm not gonna bother checking...
     283   
     284    //Shutdown both ends, assume we have all data...
     285    d_shutdown(TargetSocket, 2);
     286   
     287    d_closesocket(TargetSocket);
     288   
     289    //Make sure we can't use the old handle again...
     290    TargetSocket = INVALID_SOCKET;
     291  }
     292}
     293
     294int GetData(SOCKET ClientSocket, BYTE *IOBuffer, int IOBufferSize,
     295        int ThreadNum) {
     296 
     297  int NumRecv;
     298  int Error;
     299  struct timeval Timeout;
     300  fd_set SocketSet;
     301 
     302  //Set up a socket set structure with just ClientSocket for  select(..)
     303  FD_ZERO(&SocketSet);
     304  FD_SET(ClientSocket, &SocketSet);
     305 
     306  //set timeout
     307  Timeout.tv_sec = NETIO_CONN_TIMEOUT;
     308  Timeout.tv_usec = 0;
     309 
     310  do {
     311    NumRecv = d_recv(ClientSocket, (char *) IOBuffer, IOBufferSize, 0);
     312    if (NumRecv == 0) {
     313      //Lost connect
     314      return -1;
     315     
     316    } else if (NumRecv == SOCKET_ERROR) {
     317      Error = d_WSAGetLastError();
     318      if (Error == WSAEWOULDBLOCK) {
     319    NumRecv = 0;
     320    //Wait for socket to be readable
     321    if (d_select(0, &SocketSet, NULL, NULL, &Timeout) != 1) {
     322      //Timeout
     323      return -1;
    238324    }
    239 
    240     // return an error in we couldn't find a valid port
    241     if (bind_count == MAXBINDCOUNT) return WSAEADDRINUSE;
    242 
    243     // Start listening for connections
    244     if (d_listen(ServerSocket, SOMAXCONN) == SOCKET_ERROR)
    245         return d_WSAGetLastError ();   
    246 
    247     // Set up event for new connections
    248     if (d_WSAAsyncSelect(ServerSocket, MsgWindow, SocketMsg, FD_ACCEPT) == SOCKET_ERROR)
    249         return d_WSAGetLastError ();
    250 
    251     return 0;
    252 }
    253 
    254 
    255 int AnswerListeningSocket(SOCKET ServerSocket, SOCKET &ClientSocket, SOCKADDR_IN &ClientSockAddr, int AddrLen) {
    256     if (d_WSAIsBlocking()) {
    257         log_message("rejected connect due blocking\n");
    258         return -1;
     325   
     326      } else {
     327    //Assume connection terminated
     328    return -1;
     329      }
     330    }
     331  } while(NumRecv == 0);
     332  return NumRecv;
     333}
     334
     335int GetLine(char *OutStr, SOCKET ClientSocket, BYTE *IOBuffer, int IOBufferSize,
     336        int &BufferIndex, int &DataInBuffer, int ThreadNum) {
     337 
     338  int i;
     339  char CurChar;
     340 
     341  i = 0;
     342  do {
     343    if (BufferIndex == DataInBuffer) { //Need more data
     344      DataInBuffer = GetData(ClientSocket, IOBuffer, IOBufferSize, ThreadNum);
     345      if (DataInBuffer == -1) {
     346    //Lost connect
     347    return -1;
     348      }
     349      BufferIndex = 0;
     350    }
     351    CurChar = IOBuffer[BufferIndex];
     352    BufferIndex++;
     353    if ((CurChar != 10) && (CurChar != 13))  {
     354      OutStr[i] = CurChar;
     355      i++;
     356    }
     357  } while ((CurChar != 10) && (i < NETIO_MAX_LINE));
     358  if (i == NETIO_MAX_LINE) {
     359    return -1;
     360  }
     361 
     362  OutStr[i] = 0;
     363  return 0;
     364}
     365
     366int SendData(SOCKET ClientSocket, BYTE *SendBuffer, int NumToSend,
     367         int ThreadNum) {
     368 
     369  int NumSent = 0;
     370  int Error;
     371  struct timeval Timeout;
     372  fd_set SocketSet;
     373 
     374  char NumSentStr[50];
     375  itoa(NumToSend, NumSentStr, 10);
     376 
     377  //Set up a socket set structure with just ClientSocket for  select(..)
     378  FD_ZERO(&SocketSet);
     379  FD_SET(ClientSocket, &SocketSet);
     380  //set timeout
     381  Timeout.tv_sec = NETIO_CONN_TIMEOUT;
     382  Timeout.tv_usec = 0;
     383 
     384  while (NumToSend > 0) {
     385    NumSent = d_send(ClientSocket, (char *) SendBuffer + NumSent, NumToSend, 0);
     386    if (NumSent == 0) {
     387      //Lost connect
     388      return -1;
     389    }
     390    else if (NumSent == SOCKET_ERROR) {
     391      Error = d_WSAGetLastError();
     392      if (Error == WSAEWOULDBLOCK) {
     393    NumSent = 0;
     394    if (d_select(0, NULL, &SocketSet, NULL, &Timeout) != 1) {
     395      //Timeout
     396      return -1;
    259397    }
    260 
    261     ClientSocket = d_accept(ServerSocket, (LPSOCKADDR) &ClientSockAddr, &AddrLen);
    262     if (ClientSocket == INVALID_SOCKET) {
    263         log_message("accept failed - connection lost\n");
    264         return -1;
    265     }
    266 
    267     log_message("accept success - connection made\n");
    268     return 0;
    269 }
    270 
    271 
    272 void DestroyListeningSocket(SOCKET &ServerSocket, HWND MsgWindow) {
    273     //Remove any message notification
    274     d_WSAAsyncSelect(ServerSocket, MsgWindow, 0, 0);
    275 
    276     //Close the socket
    277     CloseSocket(ServerSocket);
    278 }
    279 
    280 
    281 void CloseSocket(SOCKET &TargetSocket) {
    282     if (TargetSocket != INVALID_SOCKET) {
    283         //Since we're closing the socket, there's not much I can do about errors
    284         //now so I'm not gonna bother checking...
    285 
    286         //Shutdown both ends, assume we have all data...
    287         d_shutdown(TargetSocket, 2);
    288 
    289         d_closesocket(TargetSocket);
    290 
    291         //Make sure we can't use the old handle again...
    292         TargetSocket = INVALID_SOCKET;
    293     }
    294 }
    295 
    296 
    297 int GetData(SOCKET ClientSocket, BYTE *IOBuffer, int IOBufferSize,
    298                                                     int ThreadNum) {
    299 
    300     int NumRecv;
    301     int Error;
    302     struct timeval Timeout;
    303     fd_set SocketSet;
    304 
    305     //Set up a socket set structure with just ClientSocket for  select(..)
    306     FD_ZERO(&SocketSet);
    307     FD_SET(ClientSocket, &SocketSet);
    308 
    309     //set timeout
    310     Timeout.tv_sec = NETIO_CONN_TIMEOUT;
    311     Timeout.tv_usec = 0;
    312 
    313     do {
    314         NumRecv = d_recv(ClientSocket, (char *) IOBuffer, IOBufferSize, 0);
    315         if (NumRecv == 0) {
    316             //Lost connect
    317             return -1;
    318 
    319         } else if (NumRecv == SOCKET_ERROR) {
    320             Error = d_WSAGetLastError();
    321             if (Error == WSAEWOULDBLOCK) {
    322                 NumRecv = 0;
    323                 //Wait for socket to be readable
    324                 if (d_select(0, &SocketSet, NULL, NULL, &Timeout) != 1) {
    325                     //Timeout
    326                     return -1;
    327                 }
    328 
    329             } else {
    330             //Assume connection terminated
    331             return -1;
    332             }
    333         }
    334     } while(NumRecv == 0);
    335     return NumRecv;
    336 }
    337 
    338 
    339 int GetLine(char *OutStr, SOCKET ClientSocket, BYTE *IOBuffer, int IOBufferSize,
    340                 int &BufferIndex, int &DataInBuffer, int ThreadNum) {
    341 
    342     int i;
    343     char CurChar;
    344 
    345     i = 0;
    346     do {
    347         if (BufferIndex == DataInBuffer) { //Need more data
    348             DataInBuffer = GetData(ClientSocket, IOBuffer, IOBufferSize, ThreadNum);
    349             if (DataInBuffer == -1) {
    350                 //Lost connect
    351                 return -1;
    352             }
    353             BufferIndex = 0;
    354         }
    355         CurChar = IOBuffer[BufferIndex];
    356         BufferIndex++;
    357         if ((CurChar != 10) && (CurChar != 13))  {
    358             OutStr[i] = CurChar;
    359             i++;
    360         }
    361     } while ((CurChar != 10) && (i < NETIO_MAX_LINE));
    362     if (i == NETIO_MAX_LINE) {
    363         return -1;
    364     }
    365 
    366     OutStr[i] = 0;
    367     return 0;
    368 }
    369 
    370 
    371 int SendData(SOCKET ClientSocket, BYTE *SendBuffer, int NumToSend,
    372                                 int ThreadNum) {
    373 
    374     int NumSent = 0;
    375     int Error;
    376     struct timeval Timeout;
    377     fd_set SocketSet;
    378 
    379     char NumSentStr[50];
    380     itoa(NumToSend, NumSentStr, 10);
    381 
    382     //Set up a socket set structure with just ClientSocket for  select(..)
    383     FD_ZERO(&SocketSet);
    384     FD_SET(ClientSocket, &SocketSet);
    385     //set timeout
    386     Timeout.tv_sec = NETIO_CONN_TIMEOUT;
    387     Timeout.tv_usec = 0;
    388 
    389     while (NumToSend > 0) {
    390         NumSent = d_send(ClientSocket, (char *) SendBuffer + NumSent, NumToSend, 0);
    391         if (NumSent == 0) {
    392             //Lost connect
    393             return -1;
    394         }
    395         else if (NumSent == SOCKET_ERROR) {
    396             Error = d_WSAGetLastError();
    397             if (Error == WSAEWOULDBLOCK) {
    398                 NumSent = 0;
    399                 if (d_select(0, NULL, &SocketSet, NULL, &Timeout) != 1) {
    400                     //Timeout
    401                     return -1;
    402                 }
    403             }
    404             else {
    405                 //Lost Connection
    406                 return -1;
    407             }
    408         }
    409         NumToSend -= NumSent;
    410     }
    411     return 0;
    412 }
    413 
     398      }
     399      else {
     400    //Lost Connection
     401    return -1;
     402      }
     403    }
     404    NumToSend -= NumSent;
     405  }
     406  return 0;
     407}
    414408
    415409
     
    433427 */
    434428DWORD GetHostID () {
    435      char szLclHost [MAXHOSTNAME];
    436      LPHOSTENT lpstHostent;
    437      SOCKADDR_IN stLclAddr;
    438      SOCKADDR_IN stRmtAddr;
    439      int nAddrSize = sizeof(SOCKADDR);
    440      SOCKET hSock;
    441      int nRet;
    442 
    443      /* Init local address (to zero) */
    444      stLclAddr.sin_addr.s_addr = INADDR_ANY;
    445 
    446      /* Get the local hostname */
    447      nRet = d_gethostname(szLclHost, MAXHOSTNAME);
    448      if (nRet != SOCKET_ERROR) {
    449         /* Resolve hostname for local address */
    450         lpstHostent = d_gethostbyname((LPSTR)szLclHost);
    451         if (lpstHostent)
    452           stLclAddr.sin_addr.s_addr = *((u_long FAR*) (lpstHostent->h_addr));
    453      }
    454 
    455      /* If still not resolved, then try second strategy */
    456      if (stLclAddr.sin_addr.s_addr == INADDR_ANY) {
    457         /* Get a UDP socket */
    458         hSock = d_socket(AF_INET, SOCK_DGRAM, 0);
    459         if (hSock != INVALID_SOCKET)  {
    460           /* Connect to arbitrary port and address (NOT loopback) */
    461           stRmtAddr.sin_family = AF_INET;
    462           stRmtAddr.sin_port   = d_htons(IPPORT_ECHO);
    463           stRmtAddr.sin_addr.s_addr = d_inet_addr("128.127.50.1");
    464           nRet = d_connect(hSock,
    465                               (LPSOCKADDR)&stRmtAddr,
    466                               sizeof(SOCKADDR));
    467           if (nRet != SOCKET_ERROR) {
    468              /* Get local address */
    469              d_getsockname(hSock,
    470                              (LPSOCKADDR)&stLclAddr,
    471                              (int FAR*)&nAddrSize);
    472           }
    473           d_closesocket(hSock);   /* we're done with the socket */
    474         }
    475      }
    476      return (stLclAddr.sin_addr.s_addr);
    477 }
    478 
     429  char szLclHost [MAXHOSTNAME];
     430  LPHOSTENT lpstHostent;
     431  SOCKADDR_IN stLclAddr;
     432  SOCKADDR_IN stRmtAddr;
     433  int nAddrSize = sizeof(SOCKADDR);
     434  SOCKET hSock;
     435  int nRet;
     436 
     437  /* Init local address (to zero) */
     438  stLclAddr.sin_addr.s_addr = INADDR_ANY;
     439 
     440  /* Get the local hostname */
     441  nRet = d_gethostname(szLclHost, MAXHOSTNAME);
     442  if (nRet != SOCKET_ERROR) {
     443    /* Resolve hostname for local address */
     444    lpstHostent = d_gethostbyname((LPSTR)szLclHost);
     445    if (lpstHostent)
     446      stLclAddr.sin_addr.s_addr = *((u_long FAR*) (lpstHostent->h_addr));
     447  }
     448 
     449  /* If still not resolved, then try second strategy */
     450  if (stLclAddr.sin_addr.s_addr == INADDR_ANY) {
     451    /* Get a UDP socket */
     452    hSock = d_socket(AF_INET, SOCK_DGRAM, 0);
     453    if (hSock != INVALID_SOCKET)  {
     454      /* Connect to arbitrary port and address (NOT loopback) */
     455      stRmtAddr.sin_family = AF_INET;
     456      stRmtAddr.sin_port   = d_htons(IPPORT_ECHO);
     457      stRmtAddr.sin_addr.s_addr = d_inet_addr("128.127.50.1");
     458      nRet = d_connect(hSock,
     459               (LPSOCKADDR)&stRmtAddr,
     460               sizeof(SOCKADDR));
     461      if (nRet != SOCKET_ERROR) {
     462    /* Get local address */
     463    d_getsockname(hSock,
     464              (LPSOCKADDR)&stLclAddr,
     465              (int FAR*)&nAddrSize);
     466      }
     467      d_closesocket(hSock);   /* we're done with the socket */
     468    }
     469  }
     470  return (stLclAddr.sin_addr.s_addr);
     471}
Note: See TracChangeset for help on using the changeset viewer.