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

📄 wal.c

📁 windows 网络编程。pdf文档
💻 C
📖 第 1 页 / 共 5 页
字号:
/*---------------------------------------------------------------------
 *
 *  Program: WAL.EXE  WinSock Application Launcher
 *
 *  filename: wal.c
 *
 *  copyright by Bob Quinn, 1995
 *
 *  Description:
 *    WinSock test and performance analysis application that allows
 *    launching of tcp or udp, clients or servers, using blocking,
 *    non-blocking or asynchronous operation modes.  Socket options
 *    and many application I/O parameters are available to alter
 *    the application operation before or during execution.
 *
 *  This software is not subject to any  export  provision  of
 *  the  United  States  Department  of  Commerce,  and may be
 *  exported to any country or planet.
 *
 *  Permission is granted to anyone to use this  software  for any  
 *  purpose  on  any computer system, and to alter it and redistribute 
 *  it freely, subject to the following  restrictions:
 *
 *  1. The author is not responsible for the consequences of
 *     use of this software, no matter how awful, even if they
 *     arise from flaws in it.
 *
 *  2. The origin of this software must not be misrepresented,
 *     either by explicit claim or by omission.  Since few users
 *     ever read sources, credits must appear in the documentation.
 *
 *  3. Altered versions must be plainly marked as such, and
 *     must not be misrepresented as being the original software.
 *     Since few users ever read sources, credits must appear in
 *     the documentation.
 *
 *  4. This notice may not be removed or altered.
 *	 
 ---------------------------------------------------------------------*/
#include <windows.h>
#include <winsock.h> /* Windows Sockets */
#include <windowsx.h>	/* for WinNT */
#include <string.h> /* for _fmemcpy() & _fmemset() */

#include "..\winsockx.h"
#include "wal.h" 

/*------------ global variables ------------*/
char szWALClass   [] = "WinSock Application Launcher";

int  wChargenLen;				/* length of string to be output */
char achChargenBuf[2*BUF_SIZE];	/* we put CHARGEN_SEQ string resource here */
int  cbBufSize;

char achInBuf  [BUF_SIZE];  /* Input Buffer */
char achOutBuf [BUF_SIZE];  /* Output Buffer */

int recv_count;	/* number of calls to recv() on FD_READ */
                                                
/* socket name structures (for IP addresses & ports) */
struct sockaddr_in stLclSockName, stRmtSockName;

BOOL bShowDetail = FALSE;	/* toggle for detail statistics */

u_long lCallCount=0;	/* Total number I/O function calls */
WSAPP stWSAppData;		/* Application data */

/* Table of application ID's from which we launch based on user choice */
int anWSAppTable[2][2][3] = {	/* Role, Protocol, Mode */
	BL_DS_CL, NB_DS_CL, AS_DS_CL, 
	BL_DG_CL, NB_DG_CL, AS_DG_CL, 
	BL_DS_SV, NB_DS_SV, AS_DS_SV, 
	BL_DG_SV, NB_DG_SV, AS_DG_SV, 
};

/* strings describing the current socket state */
static LPSTR szSockState[] = {
	"none (no socket)", 
	"open", 
	"named (bound)",
	"listening",
	"accept pending",
	"connect pending",
	"connected",
	"close pending"
};

/* this table translates our I/O mode index into the WM_COMMAND I/O mode message */
int anIoCmd[] = {
	IDM_WRITE_READ,
	IDM_READ_WRITE,
	IDM_READ,
	IDM_WRITE
};

/* this table contains default settings and it's indexed by operation mode 
 *  (e.g. OPMODE_BL, OPMODE_NB, or OPMODE_AS) */
OPMODEOPTION astOpModeOption[] = {
	/* fields: nIoMode, nLength, nLoopLimit, nWinTimer, nBytesMax */
	{"Blocking",	IOMODE_WR,DIX_MSS,	DFLT_LOOP_MAX,200,0},	/* blocking mode */
	{"NonBlocking",	IOMODE_RW,DIX_MSS,	DFLT_LOOP_MAX,50, 0},	/* non-blocking mode */
	{"Asynchronous",IOMODE_R, DIX_MSS,	DFLT_LOOP_MAX,0,  0}	/* asynchronous mode */
};
/* BQ NOTE: I need to find out how to make GetProfileString look in the
 *  same directory where the executable resides */
char szIniFile[] = "WAL.INI";
char szAppOption[] = "AppOptions";

/* this table contains default settings, and it's indexed by I/O mode 
 * (e.g. read/write, write/read, read or write) and App role (client or server) */
IOMODEOPTION astIoModeOption[][2] = {
	/* Client Role:				Server Role: */
	{{ECHO_PORT, "echo"},		{CHARGEN_PORT, "chargen"}},	/* Write/Read mode */
	{{CHARGEN_PORT, "chargen"},	{ECHO_PORT, "echo"}},		/* Read/Write mode */
	{{CHARGEN_PORT, "chargen"},	{DISCARD_PORT, "discard"}},		/* Read-only mode */
	{{DISCARD_PORT, "discard"},	{CHARGEN_PORT, "chargen"}}	/* Write-only mode */
};

WSAPP stWSAppData;		/* Our Application's Datastructure */

HWND FAR PASCAL WALInit(HANDLE, HANDLE, int);
/*--------------------------------------------------------------------
 *  Function: WinMain()
 *
 *  Description: 
 *     initialize and start message loop
 *
 */
int PASCAL WinMain
	(HANDLE hInstance,
	 HANDLE hPrevInstance,
	 LPSTR  lpszCmdLine,
	 int    nCmdShow)
{
    MSG msg;
    int nRet;
    HWND hwnd;
    
    hInst = hInstance;
    
    lpszCmdLine = lpszCmdLine; /* avoid warning */

    hwnd = WALInit(hInstance, hPrevInstance, nCmdShow);	/* initialize! */
    if (!hwnd) 	
        return 0;

	/*-------------Initialize Windows Sockets DLL------------*/
	nRet = WSAStartup(WS_VERSION_REQD, &stWSAData);
	/* WSAStartup() returns error value if failed (0 on success) */
	if (nRet != 0) {		
   		WSAperror(nRet, "WSAStartup()", hInst);
   	}
        	
    while (GetMessage (&msg, NULL, 0, 0)) {		/* main loop */
        TranslateMessage(&msg);
        DispatchMessage (&msg);
    }
    
	/*-------------say good-by to WinSock DLL----------------*/
	if (!nRet) {  /* only call if WSAStartup() succeeded */
	    nRet = WSACleanup();
	    if (nRet == SOCKET_ERROR) {
       		WSAperror(WSAGetLastError(), "WSACleanup()", hInst);
	    }
	}
    return msg.wParam;
} /* end WinMain() */


/*----------------------------------------------------------------------
 * Function: WALInit()
 *
 * Description: Register Window class, create and show main window.
 */
HWND FAR PASCAL WALInit(HANDLE hInst, HANDLE hPrevInst, int nCmdShow)
{
    WNDCLASS  wc;
    HWND 	hwnd;

	if (!hPrevInst) {
    	/* register WAL's window class */
    	wc.style         = CS_HREDRAW | CS_VREDRAW;
#pragma warning (disable:4050)
    	wc.lpfnWndProc   = WALWndProc;
    	wc.cbClsExtra    = 0;
    	wc.cbWndExtra    = 0;
    	wc.hInstance     = hInst;
    	wc.hIcon         = LoadIcon(hInst, IDWALICON);
    	wc.hCursor       = LoadCursor(NULL,IDC_ARROW);
    	wc.hbrBackground = COLOR_APPWORKSPACE+1;
    	wc.lpszMenuName  = IDWALMENU;
    	wc.lpszClassName = szWALClass;
   		
   		if (!RegisterClass (&wc)) {
        	return (0);
        }
    }
    
    hwnd = CreateWindow(
    	szWALClass,
        szWALClass,
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        500,
        300,
        NULL,
        NULL,
        hInst,
        NULL
    );                                                    

    if (!hwnd)
        return (0);
        
    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);
    return (hwnd);
    ;
} /* end WALInit() */
                    
/*----------------------------------------------------------------------
 * Function: do_stats()
 *
 * Description: Update on-screen statistics (we do this each time we
 *  get a timer message, or when user chooses UpdateStats command.
 */
void do_stats (HANDLE hwnd, HANDLE hInst, BOOL bUpdateDetail)
{   
	PAINTSTRUCT ps;
	HDC hdc;
	u_long lSeconds, lOutRate=0L, lInRate=0L;
	int i, wRet, nSockState, XPos, YPos;
	u_long lCallRate;

	/*
	 *   Display some stats.
	 */
	InvalidateRect(hwnd, NULL, TRUE);
	hdc = BeginPaint(hwnd, &ps);

    /* Calculate time elapsed (in seconds) iff we're connected */
    if (stWSAppData.nSockState == STATE_CONNECTED) {
		lSeconds = (GetTickCount() - stWSAppData.lStartTime); 
		if (lSeconds)  	/* avoid divide by zero */
			lSeconds /= 1000L;
		if (!lSeconds)  /* avoid divide by zero */
			lSeconds = 1L;
		stWSAppData.lSeconds = lSeconds;	/* time elapsed */
	} else {
		lSeconds = stWSAppData.lSeconds;	/* final time */
	}
						         
    XPos = X_START_POS;	/* start position for statistics output */
    YPos = Y_START_POS;						         
						         
	wsprintf(achOutBuf, "Bytes Out:     %lu   In: %lu", 
		stWSAppData.lBytesOut, stWSAppData.lBytesIn);
	TextOut(hdc, XPos, YPos, achOutBuf, _fstrlen((LPSTR)achOutBuf));
	YPos += STATTEXT_HGHT;
                       
	if (stWSAppData.lBytesOut)	/* avoid divide by zero */
		lOutRate = stWSAppData.lBytesOut/lSeconds;
	if (stWSAppData.lBytesIn)
		lInRate = stWSAppData.lBytesIn/lSeconds;
	wsprintf(achOutBuf, "Bytes/Sec Out: %lu   In: %lu",lOutRate, lInRate); 
	TextOut(hdc, XPos, YPos, achOutBuf, _fstrlen((LPSTR)achOutBuf));
	YPos += STATTEXT_HGHT;
			
	wsprintf(achOutBuf, "Time Up: %lu seconds", (lSeconds==1 ? 0 : lSeconds));
	TextOut(hdc, XPos, YPos, achOutBuf, _fstrlen((LPSTR)achOutBuf));
	YPos += STATTEXT_HGHT;

	wsprintf(achOutBuf, "Timer: %d,  Loops: %d (max: %d),  Bytes per IO: %d", 
		stWSAppData.nWinTimer, stWSAppData.nLoopLimit, 
		stWSAppData.nLoopMax, stWSAppData.nLength);
	TextOut(hdc, XPos, YPos, achOutBuf, _fstrlen((LPSTR)achOutBuf));
	YPos += STATTEXT_HGHT;

	nSockState = stWSAppData.nSockState;    
	for (i=0; nSockState; i++) {	 /* convert bit flag to index */
		nSockState = nSockState >> 1;
	}
	wsprintf(achOutBuf, "Socket: %d,  Socket State: %s",
		stWSAppData.nSock, szSockState[i]);
	TextOut(hdc, XPos, YPos, achOutBuf, _fstrlen((LPSTR)achOutBuf));
	YPos += STATTEXT_HGHT*2;	/* skip a line */
	
	/* If OOB enabled, show OOB data statistics */
	if (stWSAppData.nOptions & OPTION_OOBSEND) {
		wsprintf(achOutBuf, "OOB data bytes Out: %lu   In: %lu",
			stWSAppData.lOobBytesOut, stWSAppData.lOobBytesIn);
		TextOut(hdc, XPos, YPos, achOutBuf, _fstrlen((LPSTR)achOutBuf));
		YPos += STATTEXT_HGHT*2; /* skip a line */
	}
	
	/* Update Details (if requested and we have a socket) */
	if (bUpdateDetail && (stWSAppData.nSockState > STATE_NONE)) {
		int nLen = sizeof (struct sockaddr_in);
		
		_fmemset ((void FAR*)&stLclSockName, 0, nLen);
		_fmemset ((void FAR*)&stRmtSockName, 0, nLen);
		
		/* Get Local Socket Name (if we have a socket) */
		wRet = getsockname (stWSAppData.nSock,
			(struct sockaddr FAR *)&stLclSockName, 
			(int FAR*)&nLen);
		if (wRet == SOCKET_ERROR) {
			WSAperror((int)WSAGetLastError(), "getsockname()", hInst);
		} else if (stWSAppData.nSockState == STATE_CONNECTED) {
			/* Get Remote Socket Name (if we have an association) */
			wRet = getpeername (stWSAppData.nSock,
				(struct sockaddr FAR *)&stRmtSockName, 
				(int FAR *)&nLen);
			if (wRet == SOCKET_ERROR) {
				WSAperror(WSAGetLastError(),"getpeername()", hInst);
			}
		}
	} /* end if (bUpdateDetail) */
	
	/* If details were requested, show them (even if none available yet) */
	if (bShowDetail) {		
		char FAR *szIpAddr;
		
		switch (stWSAppData.nSockState) {
			case STATE_NONE:
				TextOut (hdc, XPos, YPos, 
					"No Socket Available", 19);
				break;
			case STATE_CONN_PENDING:
			case STATE_BOUND:
			case STATE_LISTENING:
			case STATE_ACCEPT_PENDING:
				TextOut (hdc, XPos, YPos, 
					"No Socket Association", 21);
				break;
			case STATE_CONNECTED:
			default:
				TextOut (hdc, XPos, YPos, 
					"getsockname() & getpeername() results:", 38);
		}
		YPos += STATTEXT_HGHT;

        szIpAddr = inet_ntoa (stLclSockName.sin_addr);
		wsprintf(achOutBuf, "Local Port: %d, IP Address: %s",
			htons (stLclSockName.sin_port),
			szIpAddr ? szIpAddr : "unknown");
		TextOut(hdc, XPos, YPos, achOutBuf, _fstrlen((LPSTR)achOutBuf));
		YPos += STATTEXT_HGHT;
        
        szIpAddr = inet_ntoa (stRmtSockName.sin_addr);
		wsprintf(achOutBuf, "Remote Port: %d, IP Address: %s",
			htons (stRmtSockName.sin_port),
			szIpAddr ? szIpAddr : "unknown");
		TextOut(hdc, XPos, YPos, achOutBuf, _fstrlen((LPSTR)achOutBuf));
		YPos += STATTEXT_HGHT*2;
		
		lCallRate = stWSAppData.lCallCount / lSeconds;
		wsprintf (achOutBuf, "I/O calls per second: %lu", lCallRate);
		TextOut(hdc, XPos, YPos, achOutBuf, _fstrlen((LPSTR)achOutBuf));
		YPos += STATTEXT_HGHT;
		
		wsprintf (achOutBuf, "back-to-back I/O calls %d (max: %d)",
			stWSAppData.nLoopsDn, stWSAppData.nLoopsDnMax);
		TextOut(hdc, XPos, YPos, achOutBuf, _fstrlen((LPSTR)achOutBuf));
		YPos += STATTEXT_HGHT;

		wsprintf (achOutBuf, "well spaced I/O calls %d (max: %d)",
			stWSAppData.nLoopsUp, stWSAppData.nLoopsUpMax);
		TextOut(hdc, XPos, YPos, achOutBuf, _fstrlen((LPSTR)achOutBuf));
		
#ifndef WIN32
		/* For debugging ...though hasn't revealed any problems yet 
		 *  (never seen more than 2 messages in task queue or 1 in
		 *  the system message queue. These functions are in DEBUG.C */
  		ShowWinTaskQ(hwnd);	/* output task queue info to debug */
		ShowSystemQ(hdc, XPos, YPos+STATTEXT_HGHT);
#endif
	}

⌨️ 快捷键说明

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