⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nonblkng.c

📁 windows 网络编程。pdf文档
💻 C
📖 第 1 页 / 共 3 页
字号:
		goto AppExit;
	}
	/*-------------------------------------*/
	stWSAppData.nSockState = STATE_LISTENING;
	/*-------------------------------------*/
	
	do_stats(hwnd, hInst, FALSE);	/* update window to show current state */
	
	/*-------------------- begin using select() --------------------
	 * There is no good way to detect an incoming connection with
	 *  a non-blocking socket (or non-blocking operation).  Looping
	 *  on accept() is possible (expecting WSAEWOULDBLOCK), but it
	 *  incurs lots of CPU overhead. 
	 *
	 *  Since a non-blocking loop requires a blocking hook function 
	 *  anyway (to yield in Windows 3.x), we might as well use a 
	 *  blocking operation.  Using the select() function to detect
	 *  "readability" is the most common and acceptable way to do 
	 *  detect an incoming connection request (i.e. the "time to
	 *  accept()" event).
	 */
	 /* Now wait for "readability", or an error (exception) */
	 do {
	 	/* clear all sockets from FDS structure, then put our socket 
	  	*  into the socket descriptor set */
	 	FD_ZERO((fd_set FAR*)&(stReadFDS));
	 	FD_ZERO((fd_set FAR*)&(stXcptFDS));
#pragma	message ("--> WinSock FD_SET macro generates MSVC warning C4127 <--")	
	 	FD_SET(stWSAppData.nSock, (fd_set FAR*)&(stReadFDS));
	 	FD_SET(stWSAppData.nSock, (fd_set FAR*)&(stXcptFDS));
	 
	 	/* initialize the timeout structure.  We use the same timeout as
	  	 *  our I/O polling loop.  However, we don't want to poll with
	  	 *  a zero timeout, since we don't have a blocking hook function
	  	 *  to yield we'll depend on WinSock's default blocking hook.
	  	 *  We use a nice round number for our timeout: 1 second. */
	 	stTimeOut.tv_sec  = 1;
	 	stTimeOut.tv_usec = 0;
	 
	 	wRet = select(-1,				/* call select() */
	 		(fd_set FAR*)&(stReadFDS), 
	 		NULL,
	 		(fd_set FAR*)&(stXcptFDS), 
	 		(struct timeval FAR *)&(stTimeOut));
	 		
	 	if (wRet == SOCKET_ERROR) {		/* check return */
	 		/* all errors are bad news */
	    	nb_close (hInst, hwnd);
			WSAperror(WSAGetLastError(), "select()", hInst);
	 		goto AppExit;
	 		
	 	} else if (wRet != 0) {
	 		/* check for error (exception) first */
	 		if (FD_ISSET (stWSAppData.nSock,
	 			(fd_set FAR*)&(stXcptFDS))) {
	 			/* all errors are bad news */
			    nb_close (hInst, hwnd);
				WSAperror(WSAGetLastError(), "select(excptn)", hInst);
	 			goto AppExit;
	 		}
	 		if (!(FD_ISSET (stWSAppData.nSock,
	 			 (fd_set FAR*)&(stReadFDS)))) {
	 			/* This should never happen!!!  If select returned
	 			 *  a positive value, something should be set in
	 			 *  either our exception or our read socket set  */
	 			MessageBox(hwnd,
	 				"Unexpected results from select()",
	 				"Error", MB_OK | MB_ICONHAND);
	 			nb_close(hwnd, hInst);
	 			goto AppExit;	/* bail! */
	 		}
	 	}
	 } while (wRet == 0);	/* 0 return means select() timeout expired */
	/*-------------------- end using select() --------------------*/
  
	/* Note: even though we expect accept() succeed immediately, it
	 *  could fail with "would block".  To protect, we loop on the
	 *  "would block" error.  Even in this simple loop with success
	 *  almost guaranteed, we need to have a blocking hook (yield) 
	 *  in this loop to keep from locking-up Windows 3.x. */
	do {                 
		/* Initialize the Sockets Internet Address (sockaddr_in) struct */
		_fmemset ((LPSTR)&(stRmtAddr), 0, sizeof(struct sockaddr_in));

		nAddrLen = sizeof(struct sockaddr_in);
		hNewSock = accept(stWSAppData.nSock,
			(struct sockaddr FAR*)&stRmtAddr, 
			(int FAR*)&nAddrLen); 
		if (hNewSock == INVALID_SOCKET) {
			nWSAerror = WSAGetLastError();
			if (nWSAerror != WSAEWOULDBLOCK) {
				/* anything but "would block" is bad news */
			    nb_close (hInst, hwnd);
				WSAperror(nWSAerror, "accept()", hInst);
				wRet = SOCKET_ERROR;
				goto AppExit;
			}
		} else {
			break;	/* connection accepted! */
		}
		/* yield unto the non-operating system */
		OurBlockingHook();
		
	} while (nWSAerror == WSAEWOULDBLOCK);
	/*-------------------------------------*/
	stWSAppData.nSockState = STATE_CONNECTED;
	/*-------------------------------------*/

	/* This example is a (very) limited server that can only 
	 *  handle one connection at a time.  So, we close the 
	 * listening socket now and save the newly accepted one */
	wRet = nb_close (hInst, hwnd);	/* close listening socket */
	stWSAppData.nSock = hNewSock;	/* save new (accept) socket */
                                                
    /* get timers for statistics updates & I/O (if requested) */                        
	get_timers(hInst, hwnd);
                                    
	/* Tell ourselves to do next step! */
	PostMessage(hwnd, WM_COMMAND, anIoCmd[stWSAppData.nIoMode], 0L);

AppExit:    
	return (wRet);

} /* end nb_ds_ls() */

/*---------------------------------------------------------------------------
 * Function: nb_dg_cn()
 *
 * Description:
 *  Blocking datagram "connect".
 *
 */
int nb_dg_cn (HANDLE hInst, HANDLE hwnd)
{
	struct sockaddr_in stLclAddr;		/* Socket structure */
	int	 wRet = SOCKET_ERROR;		/* work variable */
	u_long lOnOff;

	/* Get a UDP socket */
	if (stWSAppData.nSock) {
		stWSAppData.nSock = socket (AF_INET, SOCK_DGRAM, 0);
		if (stWSAppData.nSock == INVALID_SOCKET)  {
        	WSAperror(WSAGetLastError(), "socket()", hInst);
        	goto AppExit;
        }
	}
	/*---------------------------------*/
	stWSAppData.nSockState = STATE_OPEN;
	/*---------------------------------*/

	/* make our socket non-blocking */
	lOnOff = TRUE;
	wRet = ioctlsocket(stWSAppData.nSock, FIONBIO, (u_long FAR *)&lOnOff);
	if (wRet) {	/* ioctlsocket() returns 0 on success */
	    nb_close (hInst, hwnd);
		WSAperror(WSAGetLastError(), "ioctlsocket()", hInst);
		goto AppExit;
	}

	/* Initialize the Sockets Internet Address (sockaddr_in) structure */
	_fmemset ((LPSTR)&(stLclAddr), 0, sizeof(struct sockaddr_in)); 

	/* Get IP Address from a hostname (or IP address string in dot-notation) */
	stLclAddr.sin_addr.s_addr = GetAddr(stWSAppData.szHost);

	/* convert port number from host byte order to network byte order */
	stLclAddr.sin_port = htons (stWSAppData.nPortNumber);	
	stLclAddr.sin_family = PF_INET;	/* Internet Address Family */
                                             
	/*----------------------------------------*/
	stWSAppData.nSockState = STATE_CONN_PENDING;
	/*----------------------------------------*/
                                               
	wRet = connect(stWSAppData.nSock,
		(struct sockaddr FAR*)&stLclAddr, 
		sizeof(struct sockaddr_in)); 
	if (wRet == SOCKET_ERROR) {
	    nb_close (hInst, hwnd);
		WSAperror(WSAGetLastError(),"connect()", hInst);
		goto AppExit;
	}
      
	/*-------------------------------------*/
	stWSAppData.nSockState = STATE_CONNECTED;
	/*-------------------------------------*/

    /* get timers for statistics updates & I/O (if requested) */                        
	get_timers(hInst, hwnd);

	/* Tell ourselves to do next step! */
	PostMessage(hwnd, WM_COMMAND, anIoCmd[stWSAppData.nIoMode], 0L);

AppExit:    
	return (wRet);

} /* end nb_dg_cn() */

/*---------------------------------------------------------------------------
 * Function: nb_dg_ls()
 *
 * Description:
 *  Blocking datagram "listen".
 *
 */
int nb_dg_ls (HANDLE hInst, HANDLE hwnd)
{
	struct sockaddr_in stLclAddr;		/* Socket structure */
	int	 wRet = SOCKET_ERROR;		/* work variable */
	u_long lOnOff;

	/* Get a UDP socket */
	if (stWSAppData.nSockState == STATE_NONE) {
		stWSAppData.nSock = socket (AF_INET, SOCK_DGRAM, 0);
		if (stWSAppData.nSock == INVALID_SOCKET)  {
			WSAperror(WSAGetLastError(), "socket()", hInst);
        	goto AppExit;
        }
		/*---------------------------------*/
		stWSAppData.nSockState = STATE_OPEN;
		/*---------------------------------*/
	}

	/* make our socket non-blocking */
	lOnOff = TRUE;
	wRet = ioctlsocket(stWSAppData.nSock, FIONBIO, (u_long FAR *)&lOnOff);
	if (wRet) {	/* ioctlsocket() returns 0 on success */
	    nb_close (hInst, hwnd);
		WSAperror(WSAGetLastError(), "ioctlsocket()", hInst);
		goto AppExit;
	}

	/* convert port number from host byte order to network byte order */
	stLclAddr.sin_port = htons (stWSAppData.nPortNumber);	
	stLclAddr.sin_addr.s_addr = 0L;	/* don't restrict incoming address */
	stLclAddr.sin_family = PF_INET;	/* Internet Address Family */
                                              
	wRet = bind(stWSAppData.nSock,
			(struct sockaddr FAR*)&stLclAddr, 
			sizeof(struct sockaddr_in)); 
	if (wRet == SOCKET_ERROR) {
	    nb_close (hInst, hwnd);
		WSAperror(WSAGetLastError(), "bind()", hInst);
		goto AppExit;
	}
	/*---------------------------------*/
	stWSAppData.nSockState = STATE_BOUND;
	/*---------------------------------*/

	do_stats(hwnd, hInst, FALSE);	/* update window to show current state */

	/* Tell ourselves to do next step! */
	PostMessage(hwnd, WM_COMMAND, anIoCmd[stWSAppData.nIoMode], 0L);
	
AppExit:    
	return (wRet);

} /* end nb_dg_ls */

/*---------------------------------------------------------------------------
 * Function: nb_w_r()
 *
 * Description:
 *   Non-blocking write and read.  Our CLIENTS connecting to ECHO port 
 *   (by default) use this.
 */
int nb_w_r(HANDLE hInst, HANDLE hwnd)
{
	int		cbOutLen=0;             /* Bytes in Output Buffer */
	int		cbBufSize;				/* Length of I/O */
	int		i,wRet,nWSAerror;
	static  int bBusyFlag = FALSE;	/* semaphore */
	
	if (bBusyFlag)	/* use a semaphore to avoid being reentered */
		return(0);	/*  when yielding (the nesting can be fatal) */
	else
		bBusyFlag = TRUE;
                                                       
	cbBufSize = stWSAppData.nLength;                                                       

	if (stWSAppData.nOptions & OPTION_SOUND)	                                                       
		MessageBeep(0xFFFF);

		
	for (i=0; i<stWSAppData.nLoopLimit; i++, stWSAppData.wOffset++) {

	    /* adjust offset into output string buffer */
	    if (stWSAppData.wOffset >= cbBufSize) {
	    	stWSAppData.wOffset = 0;
	    }
	     
	    /* write to server */
	    cbOutLen = 0;
	    while (cbOutLen < cbBufSize) {
		    wRet = send (stWSAppData.nSock, 
		    	(LPSTR)&(achChargenBuf[stWSAppData.wOffset+cbOutLen]),
		    	(cbBufSize-cbOutLen), 0);
		    if (wRet == SOCKET_ERROR) {
		    	nWSAerror = WSAGetLastError();
		    	if (nWSAerror != WSAEWOULDBLOCK) {
	    			nb_close (hInst, hwnd);
        			WSAperror(nWSAerror,"send()", hInst);
			    	goto wr_end;
        		}
		    } else {
			/* Tally amount sent, to see how much left to send */
		    	cbOutLen += wRet;
		    	stWSAppData.lBytesOut += wRet;
		    }
	    } /* end send() loop */

	    /* read as much as we can from the server, until we get an 
	     *  error, any error (most likely one is WSAEWOULDBLOCK
	     *  which in effect means there's no more data to be read) */
	    for (;;) {
		    wRet = recv (stWSAppData.nSock, (LPSTR)achInBuf, BUF_SIZE, 0);
		    if (wRet == SOCKET_ERROR) {
		    	nWSAerror = WSAGetLastError();
		    	if (nWSAerror != WSAEWOULDBLOCK) {
				    nb_close (hInst, hwnd);
        			WSAperror(nWSAerror, "recv()", hInst);
			    	goto wr_end;	/* quit on error */
        		}
        		break;				/* WouldBlock is not fatal */
		    } else if (wRet == 0) { /* Other side closed socket */
      			MessageBox (hwnd, achOutBuf, 
					"server closed connection", MB_OK);
				do_close (hInst, hwnd, FALSE);
				goto wr_end;
		    } else {
		    	stWSAppData.lBytesIn += wRet;
		    }
        } /* end recv() loop */

       	OurBlockingHook();	/* yield */
        
	} /* end main loop */
   
wr_end:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -