WATSOCK.C
上传用户:qiye66666
上传日期:2007-01-03
资源大小:202k
文件大小:10k
源码类别:

TCP/IP协议栈

开发平台:

Visual C++

  1. #include <string.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <malloc.h>
  5. #include <dos.h>
  6. #include <windows.h>
  7. #include "tcp.h"      /* must include before watsock.h */
  8. #include "watsock.h"
  9. #define MAX_LEN  8192
  10. static L_SOCKET local_socket[MAX_SOCK];   /* an array of sockets */
  11. static int lasterror = 0 ;
  12. extern void sock_exit(void);
  13. extern int sock_init(void);
  14. extern void sock_yield(tcp_Socket *s, void(*yield_fn)());
  15. extern int sock_preread(void *s, byte *dp, int len);
  16. extern int sock_recv( void *s, char *buffer, int len );
  17. extern sock_recv_init( void *s, void *space, int len );
  18. /* --- DLL initialization --- */
  19. int PASCAL FAR LibMain(HANDLE hInstance, WORD wDataSeg, WORD wHeapSize, LPSTR lpCmdLine)
  20. {
  21.     return(1);
  22. } /* LibMain */
  23. void free_socket(SOCKET s)
  24. {
  25.   local_socket[s].type = 0 ;
  26.   local_socket[s].conn = NOTCONNECT;
  27.   local_socket[s].status = CLOSE ;
  28.   if( local_socket[s].tsock != NULL ) {
  29.       free(local_socket[s].tsock) ;
  30.       local_socket[s].tsock = NULL;            /* make sure they are NULL */
  31.   }
  32. }   
  33. int PASCAL FAR wattcp_init(void)
  34. {
  35.     int i ;
  36.     for(i=0; i < MAX_SOCK; i++) {
  37. local_socket[i].tsock = NULL;    /* make sure they are NULL */
  38. local_socket[i].conn = NOTCONNECT ;
  39. local_socket[i].status = CLOSE ;
  40.     }
  41.     i = sock_init() ;                          /* starts the wattcp kernal */
  42.     /* sock_yield(NULL,Yield);*/  /* set up to yield windows' function */
  43.     return (1) ;
  44. }
  45. /* --- Windows Socket API --- */
  46. /* socket - create a socket */
  47. SOCKET PASCAL FAR wat_socket(int domain, int type, int protocol)
  48. {
  49.     int i ;
  50.     /* search for the available socket */
  51.     for (i=0; i < MAX_SOCK; i++) {
  52.  if ( local_socket[i].status == CLOSE ) {
  53.       local_socket[i].status = OPEN;
  54.       break ;
  55.  }
  56.     }
  57.     if(i > MAX_SOCK)
  58.        return(WSAEMFILE);
  59.     if( (type != SOCK_STREAM) && (type != SOCK_DGRAM) )
  60.        return(WSAESOCKTNOSUPPORT);
  61.     local_socket[i].type = type ;
  62.     return(i);
  63. } /* wat_socket */
  64. /* connect - establish a connection to a peer */
  65. int PASCAL FAR wat_connect(SOCKET s, struct sockaddr FAR *name, int namelen)
  66. {
  67.     int type ;
  68.     longword host ;
  69.     word port, status = 1;
  70.     tcp_Socket *lsocket;  
  71.     
  72.     if( local_socket[s].status != OPEN )
  73. return(WSAENOTSOCK);            /* s is not a socket */
  74.     if( local_socket[s].conn == ISCONNECT ) 
  75. return(WSAEISCONN);             /* socket is in used */
  76.     if( !(host = name->s_ip) )
  77. return(WSAEADDRNOTAVAIL);
  78.     if( !name->s_port )  
  79. return(WSAEDESTADDRREQ);
  80.     
  81.     port = ntohs(name->s_port) ;   /* tcp_open uses host order */
  82.     
  83.     if( local_socket[s].tsock == NULL)
  84. lsocket = local_socket[s].tsock = malloc(sizeof(tcp_Socket));
  85.     if( lsocket == NULL )
  86. return(WSAENOBUFS) ;     /* can't allocate any space */
  87.     
  88.     if ( local_socket[s].type  == SOCK_STREAM ) {            
  89.  if (!tcp_open(lsocket,0,host,port,NULL)) {
  90.      free_socket( s ) ;
  91.      return(WSAENETUNREACH);             /* open fail */
  92.  }
  93.  /* poll until connected, sock_delay is parsed from wattcp.cfg */
  94.  sock_wait_established(lsocket,10,NULL,&status);
  95.     }
  96.     else if ( local_socket[s].type == SOCK_DGRAM ) {
  97.  if (!udp_open(lsocket,0,host,port,NULL)) 
  98.      return(WSAENETUNREACH);             /* open fail */
  99.    
  100.  /* update socket status */
  101.  local_socket[s].conn = ISCONNECT;
  102.     }
  103.     /* sock_err is used by the sock_wait_established routine */
  104.     sock_err:
  105. switch(status) {
  106.    case  0 :  local_socket[s].conn = ISCONNECT;
  107.       break;
  108.    case -1 :  free_socket( s ) ;
  109.       return(WSAETIMEDOUT) ;
  110. }
  111.     return(0);
  112. } /* wat_connect */
  113. /* closesocket - close a socket */
  114. int PASCAL FAR wat_closesocket(SOCKET s)
  115. {
  116.     word status = 1;
  117.     tcp_Socket *lsocket;
  118.     lsocket = local_socket[s].tsock ;
  119.     if (local_socket[s].conn != ISCONNECT) {
  120. free_socket( s );
  121. return(0) ;
  122.     }
  123.     
  124.     sock_close ( lsocket ) ;
  125.     if ( local_socket[s].type == SOCK_STREAM )     /* for TCP socket */
  126.  sock_wait_closed (lsocket,10,NULL,&status) ;  
  127.     
  128.     /* sock_err is used by the sock_wait... routine */
  129.     sock_err:
  130. switch(status) {
  131.    case 1 :  free_socket( s ) ;
  132.      break;
  133.    case -1 : return(WSAENETDOWN);
  134. }
  135.     return(0);
  136. } /* wat_closesocket */
  137. /* scan through fd_set for the number of readable sockets */
  138. int chk_read(fd_set *readfds, int rcount)
  139. {
  140.     int i, nbit = 0 ;
  141.     tcp_Socket *s;
  142.     word status ;
  143.     for (i=0; i < rcount; i++) {
  144.  s = local_socket[i].tsock ;
  145.  if(local_socket[i].conn != ISCONNECT) {
  146.     if(FD_ISSET(i,readfds))
  147.        FD_CLR(i, readfds);
  148.     continue ;
  149.  }
  150.  if(!tcp_tick( s ) )
  151.     local_socket[i].conn == CONNABORT ; /* connection aborted */
  152.  
  153.  if(!sock_dataready( s ) ) {
  154.     if(FD_ISSET(i,readfds))
  155.        FD_CLR(i,readfds);
  156.     continue ;
  157.  }
  158.  if(!FD_ISSET(i,readfds))
  159.      FD_SET(i,readfds);
  160.  nbit++ ;
  161.     }
  162.     return(nbit);
  163. }
  164. /* scan through fd_set for the number of writable sockets */
  165. int chk_write(fd_set *writefds, int wcount)
  166. {
  167.     int i, nbit = 0 ;
  168.     tcp_Socket *s;
  169.     for (i=0; i < wcount; i++) {
  170.  if (local_socket[i].conn == ISCONNECT) {
  171.      if(!FD_ISSET(i, writefds)) 
  172.  FD_SET(i, writefds) ;
  173.      nbit++ ;
  174.  }else
  175.      if( FD_ISSET(i, writefds))
  176.  FD_CLR(i, writefds) ;
  177.     }
  178.     return(nbit);
  179. }
  180. /* select - determine the status of one of more sockets */
  181. int PASCAL FAR wat_select(int nfds, fd_set FAR *readfds, fd_set FAR *writefds, fd_set FAR *exceptfds, struct timeval FAR *timeout)
  182. {
  183.     int i, nbit=0 ;
  184.     tcp_Socket *s;
  185.     longword timer; 
  186.     int rc, wc ;
  187. /*    timer = set_timeout( timeout->tv_sec ); */
  188.     timer = set_timeout( 20 ); 
  189.     if ( (readfds != (fd_set *)0) && (writefds != (fd_set *)0) ) {
  190.        rc = readfds->fd_count ;
  191.        wc = writefds->fd_count ;
  192.        while(1) {
  193.   nbit = chk_read(readfds,rc) ;
  194.   nbit += chk_write(writefds,wc) ;
  195.   if ( nbit || chk_timeout(timer)) 
  196.        break ;
  197.   win_yield() ;                           /* yield to Windows */
  198.        } 
  199.     }else if ( readfds != (fd_set *)0 )  {
  200.        rc = readfds->fd_count ;
  201.        while(1) {
  202.   nbit = chk_read(readfds,rc) ;
  203.   if ( nbit || chk_timeout(timer)) 
  204.        break ;
  205.   win_yield() ;                           /* yield to Windows */
  206.        } 
  207.     }else if ( writefds != (fd_set *)0 ) {
  208.        wc = writefds->fd_count ;
  209.        while(1) {
  210.   nbit = chk_write(writefds,wc) ;
  211.   if ( nbit || chk_timeout(timer)) 
  212.      break ;
  213.   win_yield() ;                           /* yield to Windows */
  214.        } 
  215.     }   
  216.     
  217.     return( nbit );                                                              
  218. }
  219. /* wat_receive - receive data from a socket */
  220. int PASCAL FAR wat_receive(SOCKET s, char FAR *buf, int len, int flags)
  221. {
  222.     int nc , type ;
  223.     word status ;
  224.     char bigbuf[MAX_LEN] ;
  225.     tcp_Socket *socket ;
  226.    
  227.     if ((s < 0) || (s > MAX_SOCK))  
  228. return(WSAENOTSOCK) ;
  229.     if (local_socket[s].conn == NOTCONNECT )
  230. return(0) ;   
  231.     if (local_socket[s].conn == CONNABORT ) {
  232. free_socket( s ) ;
  233. return(WSAECONNABORTED) ;     /* shutdown abortively from select */
  234.     }
  235.     socket = local_socket[s].tsock ;
  236.     type = local_socket[s].type ; 
  237.     
  238.     switch (type) {
  239. case SOCK_STREAM :                  /* tcp socket */
  240.      if(!(nc = sock_fastread(socket,buf,MAX_LEN)) ) {
  241.  if(!tcp_tick(socket)) {
  242.     local_socket[s].conn = CONNABORT ;
  243.     return(WSAECONNABORTED);
  244.  }
  245.  nc = sock_fastread(socket,buf,MAX_LEN) ;  /* try again */
  246.      }
  247.      if (nc != 0)
  248.  buf[nc] = 0 ;
  249.      break;   
  250. case SOCK_DGRAM :                   /* udp socket */
  251.      sock_recv_init(socket, bigbuf, sizeof(bigbuf)) ; /*needed for udp */
  252.      sock_mode(socket,UDP_MODE_NOCHK);  /* turn off checksums */
  253.      tcp_tick( NULL ) ;             /* chk for recv data */
  254.      nc = sock_recv(socket, buf, len) ;   /* read the data */
  255.      buf[nc] = 0;        /* must terminate it */
  256.      break;
  257.     }
  258.     
  259.     sock_err :
  260.        switch(status) {
  261.   case 1 : /*foreign host closed */
  262.    return(0) ;         /* according to spec */
  263.   case -1 : /* timedout */
  264.    return(WSAETIMEDOUT) ;
  265.        }
  266.     
  267.     return(nc);
  268. } /* wat_recv */
  269. /* send - send data on a connected socket */
  270. int PASCAL FAR wat_send(SOCKET s, char FAR *buf, int len, int flags)
  271. {
  272.     int nc , type ;
  273.     tcp_Socket *socket;
  274.     
  275.     if ((s < 0) || (s > MAX_SOCK))  
  276. return(WSAENOTSOCK) ;
  277.     if (local_socket[s].conn == NOTCONNECT )
  278. return(SOCKET_ERROR) ;   
  279.     if (local_socket[s].conn == CONNABORT )
  280. return(WSAECONNABORTED) ;     /* shutdown abortively from select */
  281.     
  282.     type = local_socket[s].type ;
  283.     socket = local_socket[s].tsock ;
  284.     
  285.     if( (type == SOCK_DGRAM) && (len < sock_tbleft(socket)) )
  286.    return(WSAEMSGSIZE);
  287.     nc = sock_puts(socket, buf);         /* send and flush on next send */
  288.     return(nc);
  289. } /* wat_send */
  290. /* gethostbyname - get host information corresponding to a hostname */
  291. struct hostent FAR * PASCAL FAR wat_gethostbyname(char FAR *name)
  292. {
  293.    static struct hostent FAR * PASCAL FAR host ;
  294.    longword  addr ;
  295.    addr = resolve(name) ;
  296.    host->h_name = name ;
  297.    host->h_aliases[0] = name ;
  298.    host->h_addrtype = PF_INET ;
  299.    host->h_length = 4 ;
  300.    host->h_addr_list[0] = (char *)addr ;
  301.    return(host);
  302. } /* wat_gethostbyname */
  303. /* inet_addr - convert a string containin a dotted address */
  304. unsigned long PASCAL FAR wat_inet_addr(char FAR *cp)
  305. {
  306.     return(resolve(cp));
  307. } /* wat_inet_addr */
  308. /* host to network byte order */
  309. u_long PASCAL FAR wat_htonl(u_long hostlong)
  310. {
  311.     return(htonl(hostlong));
  312. } /* wat_htonl */
  313. u_short PASCAL FAR wat_htons(u_short hostshort)
  314. {
  315.     return(htons(hostshort));
  316. } /* wat_htons */
  317. /* network to host byte order */
  318. u_long PASCAL FAR wat_ntohl(u_long netlong)
  319. {   
  320.     return(ntohl(netlong));
  321. } /* ntohl */
  322. u_short PASCAL FAR wat_ntohs(u_short netshort)
  323. {
  324.     return(ntohs(netshort));
  325. } /* ntohs */
  326. /* FD_ISSET supporting function */
  327. int PASCAL FAR __WSAFDIsSet(SOCKET fd, fd_set FAR *set)
  328. {
  329.     int i;
  330.     if (set == (fd_set FAR *) 0)
  331. return(0);
  332.     i = set->fd_count;
  333.     while (i--)
  334. if (set->fd_array[i] == fd)
  335.     return(1);
  336.     return(0);
  337. } /* __WSAFDIsSet */
  338. int PASCAL FAR wat_WSACleanup(void)
  339. {
  340.    sock_exit();
  341.    return(1) ;
  342. }