WATSOCK.C
资源名称:watsock.zip [点击查看]
上传用户:qiye66666
上传日期:2007-01-03
资源大小:202k
文件大小:10k
源码类别:
TCP/IP协议栈
开发平台:
Visual C++
- #include <string.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <malloc.h>
- #include <dos.h>
- #include <windows.h>
- #include "tcp.h" /* must include before watsock.h */
- #include "watsock.h"
- #define MAX_LEN 8192
- static L_SOCKET local_socket[MAX_SOCK]; /* an array of sockets */
- static int lasterror = 0 ;
- extern void sock_exit(void);
- extern int sock_init(void);
- extern void sock_yield(tcp_Socket *s, void(*yield_fn)());
- extern int sock_preread(void *s, byte *dp, int len);
- extern int sock_recv( void *s, char *buffer, int len );
- extern sock_recv_init( void *s, void *space, int len );
- /* --- DLL initialization --- */
- int PASCAL FAR LibMain(HANDLE hInstance, WORD wDataSeg, WORD wHeapSize, LPSTR lpCmdLine)
- {
- return(1);
- } /* LibMain */
- void free_socket(SOCKET s)
- {
- local_socket[s].type = 0 ;
- local_socket[s].conn = NOTCONNECT;
- local_socket[s].status = CLOSE ;
- if( local_socket[s].tsock != NULL ) {
- free(local_socket[s].tsock) ;
- local_socket[s].tsock = NULL; /* make sure they are NULL */
- }
- }
- int PASCAL FAR wattcp_init(void)
- {
- int i ;
- for(i=0; i < MAX_SOCK; i++) {
- local_socket[i].tsock = NULL; /* make sure they are NULL */
- local_socket[i].conn = NOTCONNECT ;
- local_socket[i].status = CLOSE ;
- }
- i = sock_init() ; /* starts the wattcp kernal */
- /* sock_yield(NULL,Yield);*/ /* set up to yield windows' function */
- return (1) ;
- }
- /* --- Windows Socket API --- */
- /* socket - create a socket */
- SOCKET PASCAL FAR wat_socket(int domain, int type, int protocol)
- {
- int i ;
- /* search for the available socket */
- for (i=0; i < MAX_SOCK; i++) {
- if ( local_socket[i].status == CLOSE ) {
- local_socket[i].status = OPEN;
- break ;
- }
- }
- if(i > MAX_SOCK)
- return(WSAEMFILE);
- if( (type != SOCK_STREAM) && (type != SOCK_DGRAM) )
- return(WSAESOCKTNOSUPPORT);
- local_socket[i].type = type ;
- return(i);
- } /* wat_socket */
- /* connect - establish a connection to a peer */
- int PASCAL FAR wat_connect(SOCKET s, struct sockaddr FAR *name, int namelen)
- {
- int type ;
- longword host ;
- word port, status = 1;
- tcp_Socket *lsocket;
- if( local_socket[s].status != OPEN )
- return(WSAENOTSOCK); /* s is not a socket */
- if( local_socket[s].conn == ISCONNECT )
- return(WSAEISCONN); /* socket is in used */
- if( !(host = name->s_ip) )
- return(WSAEADDRNOTAVAIL);
- if( !name->s_port )
- return(WSAEDESTADDRREQ);
- port = ntohs(name->s_port) ; /* tcp_open uses host order */
- if( local_socket[s].tsock == NULL)
- lsocket = local_socket[s].tsock = malloc(sizeof(tcp_Socket));
- if( lsocket == NULL )
- return(WSAENOBUFS) ; /* can't allocate any space */
- if ( local_socket[s].type == SOCK_STREAM ) {
- if (!tcp_open(lsocket,0,host,port,NULL)) {
- free_socket( s ) ;
- return(WSAENETUNREACH); /* open fail */
- }
- /* poll until connected, sock_delay is parsed from wattcp.cfg */
- sock_wait_established(lsocket,10,NULL,&status);
- }
- else if ( local_socket[s].type == SOCK_DGRAM ) {
- if (!udp_open(lsocket,0,host,port,NULL))
- return(WSAENETUNREACH); /* open fail */
- /* update socket status */
- local_socket[s].conn = ISCONNECT;
- }
- /* sock_err is used by the sock_wait_established routine */
- sock_err:
- switch(status) {
- case 0 : local_socket[s].conn = ISCONNECT;
- break;
- case -1 : free_socket( s ) ;
- return(WSAETIMEDOUT) ;
- }
- return(0);
- } /* wat_connect */
- /* closesocket - close a socket */
- int PASCAL FAR wat_closesocket(SOCKET s)
- {
- word status = 1;
- tcp_Socket *lsocket;
- lsocket = local_socket[s].tsock ;
- if (local_socket[s].conn != ISCONNECT) {
- free_socket( s );
- return(0) ;
- }
- sock_close ( lsocket ) ;
- if ( local_socket[s].type == SOCK_STREAM ) /* for TCP socket */
- sock_wait_closed (lsocket,10,NULL,&status) ;
- /* sock_err is used by the sock_wait... routine */
- sock_err:
- switch(status) {
- case 1 : free_socket( s ) ;
- break;
- case -1 : return(WSAENETDOWN);
- }
- return(0);
- } /* wat_closesocket */
- /* scan through fd_set for the number of readable sockets */
- int chk_read(fd_set *readfds, int rcount)
- {
- int i, nbit = 0 ;
- tcp_Socket *s;
- word status ;
- for (i=0; i < rcount; i++) {
- s = local_socket[i].tsock ;
- if(local_socket[i].conn != ISCONNECT) {
- if(FD_ISSET(i,readfds))
- FD_CLR(i, readfds);
- continue ;
- }
- if(!tcp_tick( s ) )
- local_socket[i].conn == CONNABORT ; /* connection aborted */
- if(!sock_dataready( s ) ) {
- if(FD_ISSET(i,readfds))
- FD_CLR(i,readfds);
- continue ;
- }
- if(!FD_ISSET(i,readfds))
- FD_SET(i,readfds);
- nbit++ ;
- }
- return(nbit);
- }
- /* scan through fd_set for the number of writable sockets */
- int chk_write(fd_set *writefds, int wcount)
- {
- int i, nbit = 0 ;
- tcp_Socket *s;
- for (i=0; i < wcount; i++) {
- if (local_socket[i].conn == ISCONNECT) {
- if(!FD_ISSET(i, writefds))
- FD_SET(i, writefds) ;
- nbit++ ;
- }else
- if( FD_ISSET(i, writefds))
- FD_CLR(i, writefds) ;
- }
- return(nbit);
- }
- /* select - determine the status of one of more sockets */
- int PASCAL FAR wat_select(int nfds, fd_set FAR *readfds, fd_set FAR *writefds, fd_set FAR *exceptfds, struct timeval FAR *timeout)
- {
- int i, nbit=0 ;
- tcp_Socket *s;
- longword timer;
- int rc, wc ;
- /* timer = set_timeout( timeout->tv_sec ); */
- timer = set_timeout( 20 );
- if ( (readfds != (fd_set *)0) && (writefds != (fd_set *)0) ) {
- rc = readfds->fd_count ;
- wc = writefds->fd_count ;
- while(1) {
- nbit = chk_read(readfds,rc) ;
- nbit += chk_write(writefds,wc) ;
- if ( nbit || chk_timeout(timer))
- break ;
- win_yield() ; /* yield to Windows */
- }
- }else if ( readfds != (fd_set *)0 ) {
- rc = readfds->fd_count ;
- while(1) {
- nbit = chk_read(readfds,rc) ;
- if ( nbit || chk_timeout(timer))
- break ;
- win_yield() ; /* yield to Windows */
- }
- }else if ( writefds != (fd_set *)0 ) {
- wc = writefds->fd_count ;
- while(1) {
- nbit = chk_write(writefds,wc) ;
- if ( nbit || chk_timeout(timer))
- break ;
- win_yield() ; /* yield to Windows */
- }
- }
- return( nbit );
- }
- /* wat_receive - receive data from a socket */
- int PASCAL FAR wat_receive(SOCKET s, char FAR *buf, int len, int flags)
- {
- int nc , type ;
- word status ;
- char bigbuf[MAX_LEN] ;
- tcp_Socket *socket ;
- if ((s < 0) || (s > MAX_SOCK))
- return(WSAENOTSOCK) ;
- if (local_socket[s].conn == NOTCONNECT )
- return(0) ;
- if (local_socket[s].conn == CONNABORT ) {
- free_socket( s ) ;
- return(WSAECONNABORTED) ; /* shutdown abortively from select */
- }
- socket = local_socket[s].tsock ;
- type = local_socket[s].type ;
- switch (type) {
- case SOCK_STREAM : /* tcp socket */
- if(!(nc = sock_fastread(socket,buf,MAX_LEN)) ) {
- if(!tcp_tick(socket)) {
- local_socket[s].conn = CONNABORT ;
- return(WSAECONNABORTED);
- }
- nc = sock_fastread(socket,buf,MAX_LEN) ; /* try again */
- }
- if (nc != 0)
- buf[nc] = 0 ;
- break;
- case SOCK_DGRAM : /* udp socket */
- sock_recv_init(socket, bigbuf, sizeof(bigbuf)) ; /*needed for udp */
- sock_mode(socket,UDP_MODE_NOCHK); /* turn off checksums */
- tcp_tick( NULL ) ; /* chk for recv data */
- nc = sock_recv(socket, buf, len) ; /* read the data */
- buf[nc] = 0; /* must terminate it */
- break;
- }
- sock_err :
- switch(status) {
- case 1 : /*foreign host closed */
- return(0) ; /* according to spec */
- case -1 : /* timedout */
- return(WSAETIMEDOUT) ;
- }
- return(nc);
- } /* wat_recv */
- /* send - send data on a connected socket */
- int PASCAL FAR wat_send(SOCKET s, char FAR *buf, int len, int flags)
- {
- int nc , type ;
- tcp_Socket *socket;
- if ((s < 0) || (s > MAX_SOCK))
- return(WSAENOTSOCK) ;
- if (local_socket[s].conn == NOTCONNECT )
- return(SOCKET_ERROR) ;
- if (local_socket[s].conn == CONNABORT )
- return(WSAECONNABORTED) ; /* shutdown abortively from select */
- type = local_socket[s].type ;
- socket = local_socket[s].tsock ;
- if( (type == SOCK_DGRAM) && (len < sock_tbleft(socket)) )
- return(WSAEMSGSIZE);
- nc = sock_puts(socket, buf); /* send and flush on next send */
- return(nc);
- } /* wat_send */
- /* gethostbyname - get host information corresponding to a hostname */
- struct hostent FAR * PASCAL FAR wat_gethostbyname(char FAR *name)
- {
- static struct hostent FAR * PASCAL FAR host ;
- longword addr ;
- addr = resolve(name) ;
- host->h_name = name ;
- host->h_aliases[0] = name ;
- host->h_addrtype = PF_INET ;
- host->h_length = 4 ;
- host->h_addr_list[0] = (char *)addr ;
- return(host);
- } /* wat_gethostbyname */
- /* inet_addr - convert a string containin a dotted address */
- unsigned long PASCAL FAR wat_inet_addr(char FAR *cp)
- {
- return(resolve(cp));
- } /* wat_inet_addr */
- /* host to network byte order */
- u_long PASCAL FAR wat_htonl(u_long hostlong)
- {
- return(htonl(hostlong));
- } /* wat_htonl */
- u_short PASCAL FAR wat_htons(u_short hostshort)
- {
- return(htons(hostshort));
- } /* wat_htons */
- /* network to host byte order */
- u_long PASCAL FAR wat_ntohl(u_long netlong)
- {
- return(ntohl(netlong));
- } /* ntohl */
- u_short PASCAL FAR wat_ntohs(u_short netshort)
- {
- return(ntohs(netshort));
- } /* ntohs */
- /* FD_ISSET supporting function */
- int PASCAL FAR __WSAFDIsSet(SOCKET fd, fd_set FAR *set)
- {
- int i;
- if (set == (fd_set FAR *) 0)
- return(0);
- i = set->fd_count;
- while (i--)
- if (set->fd_array[i] == fd)
- return(1);
- return(0);
- } /* __WSAFDIsSet */
- int PASCAL FAR wat_WSACleanup(void)
- {
- sock_exit();
- return(1) ;
- }