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

📄 as_echo.c

📁 windows 网络编程。pdf文档
💻 C
📖 第 1 页 / 共 2 页
字号:
/*---------------------------------------------------------------------
 *
 * Program: AS_ECHO.EXE  Asynch Echo Server (TCP)
 *
 * filename: as_echo.c
 *
 * copyright by Bob Quinn, 1995
 *   
 * Description:
 *  Server application that implements echo protocol service as
 *  described by RFC 862.  This application demonstrates simultaneous
 *  multiple user support using asynchronous operation mode.
 *
 *  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.
 *	 
 ---------------------------------------------------------------------*/
#define STRICT
#include "..\wsa_xtra.h"
#include <windows.h>
#include <windowsx.h>

#include <winsock.h>
#include "resource.h"
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
#include <dos.h>
#include <direct.h>
#include "..\winsockx.h"

/*-------------- global data -------------*/
char szAppName[] = "as_echo";

SOCKET hLstnSock=INVALID_SOCKET; /* Listening socket */
SOCKADDR_IN stLclName;           /* Local address and port number */
char szHostName[MAXHOSTNAME]={0};/* Local host name */
int  iActiveConns;               /* Number of active connections */
long lByteCount;                 /* Total bytes read */
int  iTotalConns;                /* Connections closed so far */

typedef struct stConnData {
  SOCKET hSock;                  /* Connection socket */
  SOCKADDR_IN stRmtName;         /* Remote host address & port */
  LONG lStartTime;               /* Time of connect */
  BOOL bReadPending;             /* Deferred read flag */
  int  iBytesRcvd;               /* Data currently buffered */             
  int  iBytesSent;               /* Data sent from buffer */
  long lByteCount;               /* Total bytes received */
  char achIOBuf  [INPUT_SIZE];   /* Network I/O data buffer */
  struct stConnData FAR*lpstNext;/* Pointer to next record */
} CONNDATA, *PCONNDATA, FAR *LPCONNDATA;
LPCONNDATA lpstSockHead = 0;     /* Head of the list */
 
char szLogFile[] = "as_echo.log";/* Connection log file */
HFILE hLogFile=HFILE_ERROR;
BOOL  bReAsync=TRUE;

/*------------ function prototypes -----------*/
int WINAPI WinMain (HINSTANCE, HINSTANCE, LPSTR, int);
BOOL CALLBACK Dlg_Main (HWND, UINT, UINT, LPARAM);
BOOL InitLstnSock(int, PSOCKADDR_IN, HWND, u_int);
SOCKET AcceptConn(SOCKET, PSOCKADDR_IN);
int SendData(SOCKET, LPSTR, int);
int RecvData(SOCKET, LPSTR, int);
int CloseConn(SOCKET, LPSTR, int, HWND);
void DoStats (long, long, LPCONNDATA);
LPCONNDATA NewConn (SOCKET, PSOCKADDR_IN);
LPCONNDATA FindConn (SOCKET);
void RemoveConn (LPCONNDATA);

/*--------------------------------------------------------------------
 *  Function: WinMain()
 *
 *  Description: 
 *     Initialize WinSock and display main dialog box
 */
int WINAPI WinMain
  (HINSTANCE hInstance,
   HINSTANCE hPrevInstance,
   LPSTR  lpszCmdLine,
   int    nCmdShow)
{
    MSG msg;
    int nRet;

    lpszCmdLine   = lpszCmdLine;   /* avoid warning */
    hPrevInstance = hPrevInstance;
    nCmdShow      = nCmdShow;
                      
    hInst = hInstance;	/* save instance handle */
                                                                
    /*-------------initialize WinSock DLL------------*/
    nRet = WSAStartup(WSA_VERSION, &stWSAData);
    /* WSAStartup() returns error value if failed (0 on success) */
    if (nRet != 0) {    
      WSAperror(nRet, "WSAStartup()", hInst);
      /* No sense continuing if we can't use WinSock */
    } else {
          
      DialogBox (hInst, MAKEINTRESOURCE(AS_ECHO), NULL, Dlg_Main);
    
      /*---------------release WinSock DLL--------------*/
      nRet = WSACleanup();
      if (nRet == SOCKET_ERROR)
        WSAperror(WSAGetLastError(), "WSACleanup()", hInst);
    }    
        
    return msg.wParam;
} /* end WinMain() */

/*--------------------------------------------------------------------
 * Function: Dlg_Main()
 *
 * Description:
 *  Process dialog messages and asynchronous WinSock messages.
 */
BOOL CALLBACK Dlg_Main 
  (HWND hDlg,
   UINT msg,
   UINT wParam,
   LPARAM lParam)
{                      
    LPCONNDATA lpstSock;             /* Work Pointer */
    WORD WSAEvent, WSAErr;
    SOCKADDR_IN stRmtName;
    SOCKET hSock;
    BOOL bRet = FALSE;
    int  nRet, cbRcvd, cbSent;
   
    switch (msg) {
      case WSA_ASYNC:
        /*------------------------------------- 
         * Async notification message handlers 
         *------------------------------------*/ 
        hSock = (SOCKET)wParam;                 /* socket */
        WSAEvent = WSAGETSELECTEVENT (lParam);  /* extract event */
        WSAErr   = WSAGETSELECTERROR (lParam);  /* extract error */
        lpstSock = FindConn(hSock);             /* find our socket structure */

        /* Close connection on error (don't show error message in server */
        if (WSAErr && (hSock != hLstnSock))  {
          PostMessage (hWinMain, WSA_ASYNC,
              (WPARAM)hSock, WSAMAKESELECTREPLY(FD_CLOSE,0)); 
          break;
        }
        switch (WSAEvent) {
          case FD_READ:
            if (lpstSock) {
              /* Read data from socket and write it back */
              cbRcvd = lpstSock->iBytesRcvd;
              if (((INPUT_SIZE) - cbRcvd) > 0) {
                lpstSock->bReadPending = FALSE;
                nRet = RecvData(hSock, 
                  (LPSTR)&(lpstSock->achIOBuf[cbRcvd]), 
                  INPUT_SIZE-cbRcvd);
                lpstSock->iBytesRcvd += nRet;
                lpstSock->lByteCount += nRet;
                lByteCount += nRet;
                _ltoa(lByteCount, achTempBuf, 10);
                SetDlgItemText(hWinMain, IDC_BYTE_TOTAL, achTempBuf);
              } else {
                /* No buffer space now, so defer the net read */
                lpstSock->bReadPending = TRUE;
              }
            }
            /* Now write data back to client */
            cbSent = lpstSock->iBytesSent;
            lpstSock->iBytesSent += SendData(hSock,
              (LPSTR)&(lpstSock->achIOBuf[cbSent]),
              lpstSock->iBytesRcvd - cbSent);

            /* If we sent everything we received, reset counters */  
            if (lpstSock->iBytesSent == lpstSock->iBytesRcvd) {
              lpstSock->iBytesSent = 0;
              lpstSock->iBytesRcvd = 0;
            }
            break;
          case FD_WRITE:                                             
            /* Send data (may not be any to send initially) */
            if (lpstSock && lpstSock->iBytesRcvd) {
              cbSent = lpstSock->iBytesSent;
              lpstSock->iBytesSent += SendData(hSock,
                (LPSTR)&(lpstSock->achIOBuf[cbSent]),
                lpstSock->iBytesRcvd - cbSent);

              /* If we sent everything we received, reset counters */  
              if (lpstSock->iBytesSent == lpstSock->iBytesRcvd) {
                lpstSock->iBytesSent = 0;
                lpstSock->iBytesRcvd = 0;
              }
              
              /* If there's a read pending, then do it */
              if (lpstSock->bReadPending) {
                PostMessage (hWinMain, WSA_ASYNC,
                   (WPARAM)hSock, WSAMAKESELECTREPLY(FD_READ, 0));
              }
            }
            break;
          case FD_ACCEPT:
            /* Accept the incoming data connection request */
            hSock = AcceptConn(hLstnSock, &stRmtName);
            if (hSock != INVALID_SOCKET) {
              /* get a new socket structure */
              lpstSock = NewConn(hSock, &stRmtName);
              if (!lpstSock) {
                CloseConn(hSock, (LPSTR)0, INPUT_SIZE, hWinMain);
              } else {
                iActiveConns++;
                SetDlgItemInt(hWinMain, IDC_CONN_ACTIVE, iActiveConns, FALSE);
              }
            }
            break;
          case FD_CLOSE:                    /* Data connection closed */
            if (hSock != hLstnSock) {
              /* Read any remaining data and close connection */  
              CloseConn(hSock, (LPSTR)0, INPUT_SIZE, hWinMain);
              if (lpstSock) {
                DoStats(lpstSock->lByteCount, lpstSock->lStartTime, lpstSock);
                RemoveConn(lpstSock);
                iTotalConns++;
                SetDlgItemInt(hWinMain, IDC_CONN_TOTAL, iTotalConns, FALSE);
                iActiveConns--;
                SetDlgItemInt(hWinMain, IDC_CONN_ACTIVE, iActiveConns, FALSE);
              }
            }
            break;
          default:
             break;
        } /* end switch(WSAEvent) */
        break;

      case WM_COMMAND:
        switch (wParam) {
             
           case IDC_ABOUT:
             DialogBox (hInst, MAKEINTRESOURCE(IDD_ABOUT), hDlg, Dlg_About);
             break;

           case WM_DESTROY:
           case IDC_EXIT:
             /* Close listening socket */
             if (hLstnSock != INVALID_SOCKET)
               closesocket(hLstnSock);
             
             /* Close all active connections */
             for (lpstSock = lpstSockHead; 
                  lpstSock;
                  lpstSock=lpstSock->lpstNext) {
               CloseConn(lpstSock->hSock, (LPSTR)0, INPUT_SIZE, hWinMain);
               RemoveConn(lpstSock); 
             }
             /* Write final stats, and close logfile */
             if (hLogFile != HFILE_ERROR) {
               wsprintf (achTempBuf, 
                 "Final Totals: Bytes Received: %lu, Connections: %d\r\n",
                 lByteCount, iTotalConns);
               _lwrite (hLogFile, achTempBuf, strlen(achTempBuf));
               _lclose (hLogFile);
             }
             EndDialog(hDlg, msg);
             bRet = TRUE;
             break;
                       
           default:
              break;
         } /* end case WM_COMMAND: */
         break;
           
      case WM_INITDIALOG:
        hWinMain = hDlg;	/* save our main window handle */
        
        /* Get a socket listening */
        hLstnSock = InitLstnSock (IPPORT_ECHO,&stLclName,hWinMain,WSA_ASYNC);
        
        /* Get our local info for display */
        stLclName.sin_addr.s_addr = GetHostID ();
        gethostname (szHostName, MAXHOSTNAME);
        wsprintf(achTempBuf, "Local Host: %s (%s)",
            inet_ntoa(stLclName.sin_addr),
            szHostName[0] ? (LPSTR)szHostName : (LPSTR)"<unknown>");
        SetDlgItemText (hWinMain, IDC_LOCAL_HOST, achTempBuf);
                    

⌨️ 快捷键说明

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