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

📄 wsockatm.cpp

📁 < WINDOWS网络编程>>英文版,一本详细讲解WINDOWS平台下网络编程的国外经典书籍,适合英文水平高的牛人
💻 CPP
字号:
// Module Name: wsockatm.cpp
//
// Description:
//    This is a simple Winsock ATM client/server echo program.
//    The server side requires a local interface to bind to.
//    This can be accomplished with the -l:interface option.
//    For the client side, simply specify the sever address
//    to connect to. The server handles client connections in
//    the same thread as the listening socket. This sample
//    is meant to illustrate how to use the ATM address family
//    and is not how an actual client/server should be implemented.
//
// Compile:
//    cl -o wsockatm.exe wsockatm.cpp support.cpp ws2_32.lib
//
// Command Line Parameters/Options
//    -a        Print out local ATM address
//    -s        Act as the server
//    -l if     Interface to bind to. Either the index of the
//                interface or an NSAP ATM address.
//    -r addr   Specify the server's NSAP ATM address.
//    -p port   The 2 digit selector byte (hexadecimal port number).
//
#include "support.h"

#include <stdio.h>
#include <stdlib.h>

#define MAX_ATM_ADDR_LEN        64
#define MAX_BUFFER              1024
#define NSAP_ADDR_LEN           38
#define SELECTOR_BYTE_LEN       2

WSAPROTOCOL_INFO  *lpSocketProtocol=NULL;

char szServerAddr[39],        // Server's ATM NSAP address
     szPort[3];               // Port number
BOOL bServer = FALSE;
DWORD dwInterface=-1;         // Which interfce to bind to?

//
// Function: usage
//
// Description:
//    Pring usage information.
//
void usage(char *progname)
{
    printf("usage: %s -a -s -l interface -r server-addr -p port\n", 
        progname);
    printf("       -a        Print a list of ATM interface addresses\n");
    printf("       -s        Act as server\n");
    printf("       -l if     Interface to bind to:\n");
    printf("                    Interface number (e.g. 0, 1, etc.)\n");
    printf("                    NSAP ATM address (38 character address)\n");
    printf("       -r addr   NSAP ATM address of server\n"); 
    printf("       -p port   Selector byte (2 digit hexcadecimal port number)\n");
    ExitProcess(1);
}

//
// Function: EnumerateATMAddresses
//
// Description:
//    Enumerate all ATM interfaces and print their addresses.
//
void EnumerateATMAddresses(WSAPROTOCOL_INFO *lpProtocol)
{
    SOCKET             s;
    SOCKADDR_ATM       atm_addr;
    char               szAddress[MAX_ATM_ADDR_LEN];
    DWORD              dwNumInterfaces,
                       dwAddrLen=MAX_ATM_ADDR_LEN,
                       i;

    s = WSASocket(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO,
            FROM_PROTOCOL_INFO, lpProtocol, 0, WSA_FLAG_OVERLAPPED);
    if (s == INVALID_SOCKET)
    {
        printf("WSASocket() failed: %d\n", WSAGetLastError());
        return;
    }
    dwNumInterfaces = GetNumATMInterfaces(s);

    for(i=0; i < dwNumInterfaces ;i++)
    {
        ZeroMemory((PVOID)&atm_addr, sizeof(SOCKADDR_ATM));
        ZeroMemory((PVOID)szAddress, MAX_ATM_ADDR_LEN);

        if (GetATMAddress(s, i, &atm_addr.satm_number) == FALSE)
        {
            printf("GetATMAddress failed!\n");
            break;
        }
        atm_addr.satm_family                 = AF_ATM;
        atm_addr.satm_number.AddressType     = ATM_NSAP;
        atm_addr.satm_number.NumofDigits     = ATM_ADDR_SIZE;
        atm_addr.satm_blli.Layer2Protocol    = SAP_FIELD_ANY;
        atm_addr.satm_blli.Layer3Protocol    = SAP_FIELD_ABSENT;
        atm_addr.satm_bhli.HighLayerInfoType = SAP_FIELD_ABSENT;
        if (WSAAddressToString((LPSOCKADDR)&atm_addr, sizeof(atm_addr), 
            lpProtocol, szAddress, &dwAddrLen))
        {
            printf("WSAAddressToString: %d\n", 
                WSAGetLastError());
            break;
        }             
        printf("ATM ADDRESS <%d>: '%s'\n", i,
            szAddress);
    }
    closesocket(s);

    return;
}

//
// Function: ValidateArgs
//
// Description:
//    Parse command line arguments and set global variables accordingly.
//
void ValidateArgs(int argc, char **argv)
{
    int                i;

    
    if (argc > 1)
    {
        for (i = 1; i < argc; i++)
        {
            if ( (argv[i][0] == '-') || (argv[i][0] == '/')  )
            {
                switch (tolower(argv[i][1]) )
                {
                case '?':
                    usage(argv[0]);
                    break;
                
                case 'a':   // Get my ATM address
                    EnumerateATMAddresses(lpSocketProtocol);
                    ExitProcess(1);
                    break;

                case 's':   // Act as server
                    bServer = TRUE;
                    break;

                case 'l':   // Use this local interface
                    if(i+1 < argc)
                    {
                        if(strlen(argv[i+1]) == NSAP_ADDR_LEN)
                            strncpy(szServerAddr,argv[i+1],NSAP_ADDR_LEN);
                        else if(strlen(argv[i+1]) == 1)
                            dwInterface = atoi(argv[i+1]);
                        else
                            usage(argv[0]);

                        ++i;
                    }
                    break;

                case 'r':   // server's address
                    if(i+1 < argc)
                    {
                        if(strlen(argv[i+1]) == NSAP_ADDR_LEN)
                            strncpy(szServerAddr,argv[i+1],NSAP_ADDR_LEN);
                        else
                            usage(argv[0]);

                        ++i;
                    }
                    break;

                case 'p':   // server's selector byte (port)
                    if(i+1 < argc)
                    {
                        if(strlen(argv[i+1]) == SELECTOR_BYTE_LEN)
                            strncpy(szPort,argv[i+1],SELECTOR_BYTE_LEN);
                        else
                            usage(argv[0]);
                        ++i;
                    }
                    break;

                
                default:
                    usage(argv[0]);
                    break;


                } 
            }
        } 

    }
    


    return;
}

//
// Function: main
//
// Description:
//    This function parses arguments and starts either the client or server
//    depending on the arguments. The server will enumerate local ATM 
//    interfaces if necessary and bind to a local address and wait for
//    client connections. The server handles the client connection in the
//    same thread as the listening socket. The client only handles one 
//    connection and then exits. If running the client, create a socket 
//    and connect to the server. Once connected, send a message and read it 
//    back.
//
int main(int argc, char **argv)
{
    WSADATA      wsd;
    SOCKET       s;
    DWORD        dwAddrLen = sizeof(SOCKADDR_ATM);
    SOCKADDR_ATM atm_addr;
    int          ret, 
                 i;
    char         szAddress[41];

    // Initialize Winsock and parse command line arguments
    //
    if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
    {
        printf("WSAStartup() failed!\n");
        return -1;
    }
    // Find the protocol entry supporting ATM and create a socket
    //
    lpSocketProtocol = FindProtocol();
    if (lpSocketProtocol == NULL)
    {
        printf("FindProtocol returned NULL!\n");
        return -1;
    }

    s = WSASocket(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO,
                  lpSocketProtocol, 0, WSA_FLAG_OVERLAPPED);
    if (s == INVALID_SOCKET)
    {
        printf("WSASocket() failed: %d\n", WSAGetLastError());
	return -1;
    }
    ValidateArgs(argc, argv);

    ZeroMemory((PVOID)&atm_addr, sizeof(atm_addr));
    atm_addr.satm_family                 = AF_ATM;
    atm_addr.satm_number.AddressType     = ATM_NSAP;
    atm_addr.satm_number.NumofDigits     = 20;
    atm_addr.satm_blli.Layer2Protocol    = SAP_FIELD_ABSENT;
    atm_addr.satm_blli.Layer3Protocol    = SAP_FIELD_ABSENT;
    atm_addr.satm_bhli.HighLayerInfoType = SAP_FIELD_ABSENT;

    // If an interface number was not supplied (i.e. a 38 character
    // NSAP ATM address was supplied).
    //
    if ((!bServer) || (dwInterface == -1))
    {
        strncpy(&szAddress[0], szServerAddr, 38);
        strncpy(&szAddress[38], szPort, 2);
        szAddress[40] = 0;

        AtoH((char *) &atm_addr.satm_number.Addr[0], szAddress, 20);

    }
    else
    {
        // An index was supplied, look it up and get its address
        //
        if (GetATMAddress(s, dwInterface, &atm_addr.satm_number) == FALSE)
        {
             printf("Unable to get ATM interface\n");
        }
        AtoH((char *) &atm_addr.satm_number.Addr[19], szPort, 1);
    }

    if (bServer)
    {
        SOCKET        sclient;
        SOCKADDR_ATM  atm_client;
        int           atmaddrsz = sizeof(SOCKADDR_ATM);
        DWORD         dwClientAddrLen=MAX_ATM_ADDR_LEN;
        struct fd_set fdaccept;
        char          recvbuf[MAX_BUFFER],
                      szClientAddr[MAX_ATM_ADDR_LEN],
                      szAddr[MAX_BUFFER];

        dwAddrLen = MAX_BUFFER;

        // Print out the address we're binding to
        //
        if (WSAAddressToString((LPSOCKADDR)&atm_addr, sizeof(atm_addr), 
            lpSocketProtocol, szAddr, &dwAddrLen))
        {
            printf("WSAAddressToString failed: %d\n", WSAGetLastError());
        }
        printf("Binding to: <%s>\n", szAddr);

        if (bind(s, (SOCKADDR *)&atm_addr, sizeof(atm_addr)) == SOCKET_ERROR)
        {
            printf("bind() failed; %d\n", WSAGetLastError());
            return -1;
        }
        listen(s, 7);

        FD_ZERO(&fdaccept);
        FD_SET(s, &fdaccept);

        select(0, &fdaccept, NULL, NULL, NULL);

        sclient = WSAAccept(s, (SOCKADDR *)&atm_client, &atmaddrsz, NULL, 0);
        if (sclient == INVALID_SOCKET)
        {
            printf("accept() failed; %d\n", WSAGetLastError());
            return -1;
        }

        ZeroMemory((PVOID)szClientAddr, MAX_ATM_ADDR_LEN);
        if (WSAAddressToString((LPSOCKADDR)&atm_client, sizeof(atm_client), 
            lpSocketProtocol, szClientAddr, &dwClientAddrLen))
        {
            printf("WSAAddressToString: %d\n", WSAGetLastError());
        }             
        printf("Client's ATM ADDRESS: <%s>\n", szClientAddr);        
        //
        // Handle the client connection until it closes.
        //
        while (1)
        {
            ret = recv(sclient, recvbuf, MAX_BUFFER, 0);
            if (ret == SOCKET_ERROR)
            {
                if(WSAEDISCON == WSAGetLastError())
                    printf("Connection closed by peer\n");
                else
                    printf("recv() failed: %d\n", WSAGetLastError());
                return -1;
            }
            else if (ret == 0)
            {
                printf("graceful close\n");
                break;
            }
            recvbuf[ret] = '\0';
            printf("READ: '%s'\n", recvbuf);

            ret = send(sclient, recvbuf, ret, 0);
            if (ret == SOCKET_ERROR)
            {
                if(WSAEDISCON == WSAGetLastError())
                    printf("Connection closed by peer\n");
                else 
                    printf("send() failed; %d\n", WSAGetLastError());
                return -1;
            }
            printf("WROTE %d bytes\n", ret);
        }
        closesocket(sclient);
    }
    else
    {
        
        char         sendbuf[MAX_BUFFER],
                     szAddr[MAX_BUFFER];


        dwAddrLen = MAX_BUFFER;
        
        // Connect and then send and recv data
        //
        if (WSAAddressToString((LPSOCKADDR)&atm_addr, sizeof(atm_addr), 
            lpSocketProtocol, szAddr, &dwAddrLen))
        {
            printf("WSAAddressToString failed: %d\n", WSAGetLastError());
        }
        printf("Connect to: <%s>\n", szAddr);
        if (connect(s, (SOCKADDR *)&atm_addr, sizeof(atm_addr)) == SOCKET_ERROR)
        {
            printf("connect() failed: %d\n", WSAGetLastError());
            return -1;
        }
        memset(sendbuf, 'a', 512);
        for(i=0; i < 10 ;i++)
        {
            ret = send(s, sendbuf, 64, 0);
            if (ret == SOCKET_ERROR)
            {
                if(WSAEDISCON == WSAGetLastError())
                    printf("Connection closed by peer\n");
                else
                    printf("send() failed: %d\n", WSAGetLastError());
                return -1;
            }
            printf("Sent %d bytes\n", ret);
            
            ret = recv(s, sendbuf, ret, 0);
            if (ret == SOCKET_ERROR)
            {
                if(WSAEDISCON == WSAGetLastError())
                    printf("Connection closed by peer\n");
                else
                    printf("recv() failed: %d\n", WSAGetLastError());
                return -1;
            }
            else if (ret == 0)
            {
                printf("Graceful close\n");
                break;
            }
            sendbuf[ret] = '\0';
            printf("Read: '%s'\n", sendbuf);
        }
    }
    closesocket(s);

    WSACleanup();
    return 0;
}

⌨️ 快捷键说明

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