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

📄 nonblkng.c

📁 windows 网络编程。pdf文档
💻 C
📖 第 1 页 / 共 3 页
字号:
	            
	/* Tell ourselves to do it again (if we're not 
	 *  using a timer and we're still connected)! */
	if (!stWSAppData.nWinTimer &&
	   (stWSAppData.nSockState == STATE_CONNECTED))
		PostMessage(hwnd, WM_COMMAND, IDM_WRITE_READ, 0L);

	bBusyFlag = FALSE;	/* reset semaphore */

	return (cbOutLen); 
} /* end nb_w_r() */

/*---------------------------------------------------------------------------
 * Function: nb_r_w()
 *
 * Description:
 *   Blocking read and write.  Our SERVERS providing ECHO service use this.
 */
int nb_r_w(HANDLE hInst, HANDLE hwnd)
{
	int		cbInLen;                /* Bytes in Input Buffer */
	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;	/* get the I/O size */

	if (stWSAppData.nOptions & OPTION_SOUND)	                                                       
		MessageBeep(0xFFFF);
		
	for (i=0; i<stWSAppData.nLoopLimit; i++, stWSAppData.wOffset++) {
	     
	    /* read as much as we can from client (no less than I/O length
	     *  user requested, but more than that is ok) */
	    cbInLen = 0;
	    while (cbInLen < cbBufSize) {
		    wRet = recv (stWSAppData.nSock, 
			    (LPSTR)achInBuf, BUF_SIZE, 0);
		    if (wRet == SOCKET_ERROR) {
		    	nWSAerror = WSAGetLastError();
		    	if (nWSAerror != WSAEWOULDBLOCK) {
				    nb_close (hInst, hwnd);
        			WSAperror(nWSAerror,"send()", hInst);
			    	goto rw_end;
        		}
        		/* exit recv() loop on WSAEWOULDBLOCK */
        		if (cbInLen == 0)
        			goto rw_end;	/* quit if nothing read yet */
        		else
	        		break;			/* else write out what we read */
        		
		    } else if (wRet == 0) { /* Other side closed socket */
       			MessageBox (hwnd, achOutBuf, 
					"client closed connection", MB_OK);
				do_close (hInst, hwnd, FALSE);
				goto rw_end;
		    } else {
		    	cbInLen += wRet;
		    	stWSAppData.lBytesIn += wRet;
		    }
        } /* end recv() loop */

	    /* write to client, as much as we just read */
	    cbOutLen = 0;
	    while (cbOutLen < cbInLen) {
		    wRet = send (stWSAppData.nSock, 
		    	(LPSTR)&(achInBuf[cbOutLen]), 
		    	(cbInLen-cbOutLen), 0);
		    if (wRet == SOCKET_ERROR) {
		    	nWSAerror = WSAGetLastError();
		    	if (nWSAerror != WSAEWOULDBLOCK) {
				    nb_close (hInst, hwnd);
        			WSAperror(nWSAerror, "send()", hInst);
			    	goto rw_end;
        		}
        		break;
        		
		    } 
			/* Tally amount sent, to see how much left to send */
		    cbOutLen += wRet;
		    stWSAppData.lBytesOut += wRet;
	    } /* end send() loop */
        
		OurBlockingHook();	/* yield */

	} /* end main loop */
   
	/* Datagram Servers aren't "connected" until data arrives, 
	 *  so change it now (and start timer) */
	if ((stWSAppData.nSockState < STATE_CONNECTED) &&
		(stWSAppData.nSockState > STATE_NONE)) {
	
		/*--------------------------------------*/
	    stWSAppData.nSockState = STATE_CONNECTED;
		/*--------------------------------------*/
		
    	/* get timers for statistics updates & I/O (if requested) */                        
		get_timers(hInst, hwnd);
	}
		
rw_end:
	            
	/* Tell ourselves to do it again (if we're not 
	 *  using a timer and we're still connected)! */
	if (!stWSAppData.nWinTimer && 
	    (stWSAppData.nSockState == STATE_CONNECTED)) {
		PostMessage(hwnd, WM_COMMAND, IDM_READ_WRITE, 0L);
	}
                        
	bBusyFlag = FALSE;	/* reset semaphore */
                        
	return (cbOutLen); 
} /* end nb_r_w() */

/*---------------------------------------------------------------------------
 * Function: nb_r()
 *
 * Description:
 *   Non-blocking read
 */
int nb_r(HANDLE hInst, HANDLE hwnd)
{
	int		cbInLen;                /* Bytes in Input Buffer */
	int		cbBufSize;				/* Length of I/O */
	char	achInBuf  [BUF_SIZE];   /* Input Buffer */
	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 (cbInLen=0, i=0; i<stWSAppData.nLoopLimit; i++) {

	    /* read as much as we can from server */
	    wRet = recv (stWSAppData.nSock, 
		    (LPSTR)achInBuf, BUF_SIZE, 0);
	    if (wRet == SOCKET_ERROR) {
	    	nWSAerror = WSAGetLastError();
	    	if (nWSAerror != WSAEWOULDBLOCK) {
			    nb_close (hInst, hwnd);
       			WSAperror(nWSAerror, "send()", hInst);
       		}
		    break;	/* break on any error (including WSAEWOULDBLOCK) */
		    
	    } else if (wRet == 0) { /* Other side closed socket */
   			MessageBox (hwnd, achOutBuf, 
				"server closed connection", MB_OK);
			do_close(hInst, hwnd, FALSE);
			break;
			
	    } else {
		    /* tally amount received */
		    cbInLen += wRet;
		    
			/* Datagram Servers aren't "connected" until 
	 		 *  data arrives,  so change it now (and start timer) */
			if ((stWSAppData.nSockState < STATE_CONNECTED) &&
				(stWSAppData.nSockState > STATE_NONE)) {
			
				/*--------------------------------------*/
				stWSAppData.nSockState = STATE_CONNECTED;
				/*--------------------------------------*/
	    
				get_timers(hwnd, hInst);
			}
	    }
	    
	    OurBlockingHook();	/* yield */
	    
	} /* end main loop */
	
	/* tally what we read */
	stWSAppData.lBytesIn += cbInLen;
	
	/* Tell ourselves to do it again (if we're not 
	 *  using a timer and we're still connected)! */
//	if ((!stWSAppData.nWinTimer) && 
//	   	(stWSAppData.nSockState == STATE_CONNECTED))
		PostMessage(hwnd, WM_COMMAND, IDM_READ, 0L);

	bBusyFlag = FALSE;	/* reset semaphore */

	return (cbInLen);
} /* end nb_r() */

/*---------------------------------------------------------------------------
 * Function: nb_w()
 *
 * Description:
 *   Non-blocking write
 */
int nb_w(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);
        		}
        		break; /* break on any error */
		    } else {
			    /* Tally amount sent */
			    cbOutLen += wRet;
			    stWSAppData.lBytesOut += wRet;
		    }
	    } /* end send() loop */
	    
		OurBlockingHook();	/* yield */
		
	} /* end main loop */

	/* Tell ourselves to do it again (if we're not 
	 *  using a timer and we're still connected)! */
	if (!stWSAppData.nWinTimer && 
	   (stWSAppData.nSockState == STATE_CONNECTED))
		PostMessage(hwnd, WM_COMMAND, IDM_WRITE, 0L);
		
	bBusyFlag = FALSE;	/* reset semaphore */

	return (cbOutLen); 
} /* end nb_w() */

/*---------------------------------------------------------------------------
 * Function: nb_close()
 *
 * Description:
 *  Differences between this and a non-blocking close is that this cannot 
 *  handle an WSAEWOULDBLOCK error gracefully (i.e. ignore it ), and this  
 *  will* handle WSAEINPROGRESS gracefully.
 */
int nb_close (HANDLE hInst, HANDLE hwnd) 
{   
	int wRet, nWSAerror;	/* work variables */
	
	/* we may have already set this state earlier, 
	 *  but not in all cases */
	/*------------------------------------------*/
	stWSAppData.nSockState = STATE_CLOSE_PENDING;	
	/*-----------------------------------------*/

	/* Cancel any pending blocking operation */
	if (WSAIsBlocking()) {
		WSACancelBlockingCall();
	}
	                                       
    /* Doing a close without calling shutdown(how=1), and looping on
     *  recv() first--the way we do in CloseConn() in our WinSockX.lib--
     *  is dangerous and not robust ...but we're experimenting here */
	nWSAerror = 0;	                                                     
    wRet = closesocket(stWSAppData.nSock);
    if (wRet == SOCKET_ERROR) {
    	nWSAerror = WSAGetLastError();
		/* if not "would block" error, report it! */
    	if ((nWSAerror != WSAEWOULDBLOCK) && IsWindow(hwnd)) {
       		WSAperror(nWSAerror, "closesocket()", hInst);
       	}
	}
    
    /* Socket is invalid now (if it wasn't already) */
	/*---------------------------------*/
    stWSAppData.nSockState = STATE_NONE;
	/*---------------------------------*/
	
	/* free the timer resource(s) (if window not destroyed yet) */
	if (IsWindow (hwnd)) {
		KillTimer (hwnd, STATS_TIMER_ID);
		if (stWSAppData.nWinTimer)
			KillTimer (hwnd, APP_TIMER_ID);
	}

	return (wRet);
}  /* end nb_close() */

/*---------------------------------------------------------------------------
 * Function: OurBlockingHook()
 *
 * Description:
 */
void OurBlockingHook () {
	BOOL bRet;
	MSG msg;
	int i;
	                         
	/* loop on messages, but don't loop forever */
	for (i = 0; i < DFLT_LOOP_MAX; i++) {
		bRet = (BOOL)PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
		if (bRet) {
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		} else {
			break;	/* leave, if nothing to do */
		}
	}
	return;
} /* end OurBlockingHook() */

⌨️ 快捷键说明

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