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

📄 sockspx.c

📁 windows 网络编程。pdf文档
💻 C
📖 第 1 页 / 共 2 页
字号:
// Module Name: sockspx.c
//
// Description:
//    This sample illustrates using IPX/SPXII client and 
//    servers. The server is very simple and can only handle
//    one client connection at a time.
// 
// Compile:
//    cl sockspx.c ws2_32.lib
//
// Command Line Parameters/Options:
//    sockspx.c -s -c -n:IPX-Addr -e:Socket -l:IPX-Addr -p:[d|s|p]
//              -m -b:bytes -r:num
//    -s           Act as server
//    -c           Act as client
//    -n:IPX-Addr  Servers IPX addr (AABBCCDD.AABBCCDDEEFF)
//    -e:Socket    Socket enpoint server is listening on
//    -l:IPX-Addr  Local IPX address
//    -p:[d|s|p]   Protocol to use
//       d           Datagram   (IPX)
//       s           Stream     (SPXII)
//       p           Seq Packet (SPXII)
//    -m           Enumerate local IPX addresses
//    -b:Bytes     Number of bytes to send
//    -r:Num       How many sends to perform (client only)
//
//    To run the application as a server, the following command 
//    line can be specified:
//    
//        sockspx -s -e:8000 -p:s
//        
//    To run the application to act as a client, the following 
//    command line can be specified:
//        
//        sockspx -c -n AABBCCDD.AABBCCDDEEFF -e 8000 -p s
//    
//    To enumerate the local IPX adapters, the following command 
//    line will have to be specified:
//        
//        sockspx -m
//

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

#include <wsipx.h>
#include <wsnwlink.h> 

#define MAX_DATA_LEN 64000


//
// Global Variables
//

BOOL   bServer = TRUE,           // client or server
       bEnumerate = FALSE;       // enumerate addresses

SOCKET sock = INVALID_SOCKET,
       newsock = INVALID_SOCKET;
char  *pszServerAddress,         // Server's IPX address string
      *pszLocalAddress,          // Local IPX address string
      *pszServerEndpoint,        // Server's endpoint (socket) string
       chProtocol = 's';         // Protocol
DWORD  dwNumBytes=512,           // Number of bytes to send
       dwNumToSend=5;            // Number of times to send

//
// Function: CreateSocket
//
// Description:
//    Create a socket based upon the command line parameters. This 
//    creates the main socket (i.e. the listening socket for the 
//    server and the connecting socket for the client).
//    SPX sockets use either SOCK_STREAM or SOCK_SEQPACKET but must
//    be of the protocol NSPROTO_SPX or NSPROTO_SPXII.
//    IPX sockets must use SOCK_DGRAM and NSPROTO_IPX.
//
void CreateSocket()
{
    int  proto,
         sockettype;

    // Find out the socket type
    //
    if (chProtocol == 'd')
        sockettype = SOCK_DGRAM;
    else if (chProtocol == 's')
        sockettype = SOCK_STREAM;
    else
        sockettype = SOCK_SEQPACKET;
    //
    // Get the protocol
    //
    if (chProtocol == 'd')
        proto = NSPROTO_IPX;
    else
        proto = NSPROTO_SPX;

    sock = socket(AF_IPX, sockettype, proto);
    if (sock == INVALID_SOCKET)
    {
        printf("socket() failed: %d\n", WSAGetLastError());
        return;
    }
    return;
}

//
// Function: usage
//
// Description:
//    Print the usae information.
//
void usage(char *progname)
{
    printf("usage:  %s [-s|-c] -e:Socket -n:ServerAddr \
-l:LocalAddr -p:[d|s|p] -m -b:bytes\n", progname );
    printf("\t -s           Act as server (default)\n");
    printf("\t -c           Act as client\n");
    printf("\t -e:Socket    Server's socket (port)\n" );
    printf("\t -n:Addr      Server's IPX Address\n" );    
    printf("\t -l:Addr      Local IPX Address\n" );    
    printf("\t -p:d|s|p     Protocol type\n");
    printf("\t    d         datagram (IPX)\n");
    printf("\t    s         stream   (SPXII)\n");
    printf("\t    p         sequenced packet (SPXII)\n");
    printf("\t -m           Enumerate Local Addresses\n");
    printf("\t -b:int       Number of bytes to send\n");
    printf("\t -r:num       Number of repitions to send\n");
       
    ExitProcess(-1);
}

//
// Function: PrintIpxAddress
//
// Description:
//    This function prints out an IPX address in human readable
//    form.
// 
void PrintIpxAddress(char *lpsNetnum, char *lpsNodenum)
{
    int i;
        
    // Print the network number first
    //
    for (i=0; i < 4 ;i++)
    {
        printf("%02X", (UCHAR)lpsNetnum[i]);
    }
    printf(".");
    //
    // Print the node number
    // 
    for (i=0; i < 6 ;i++)
    {
        printf("%02X", (UCHAR) lpsNodenum[i]);
    }
    printf("\n");

    return;
}

//
// Function: BtoH
//
// Description:
//    BtoH () returns the equivalent binary value for an individual
//    character specified in the ascii format.
//
UCHAR BtoH(char ch)
{
    if ((ch >= '0') && (ch <= '9'))
    {
        return (ch - '0');
    }
    if ((ch >= 'A') && (ch <= 'F'))
    {
        return (ch - 'A' + 0xA);
    }
    if ((ch >= 'a') && (ch <= 'f'))
    {
        return (ch - 'a' + 0xA);
    }
    //
    // Illegal values in the IPX address will not be accepted
    //
    printf("Illegal characters in IPX address!\n");
        
    ExitProcess(-1);
}

//
// Function: AtoH
//
// Description:
//    AtoH () coverts the IPX address specified in the string
//    (ascii) format to the binary (hexadecimal) format.
//
void AtoH(char *szDest, char *szSource, int iCount)
{
    while (iCount--)
    {
        *szDest++ = (BtoH(*szSource++) << 4) + BtoH(*szSource++);
    }
    return;
}


//
// Function: FillIpxAddress
//
// Description:
//    FillIpxAddress() fills a structure of type SOCKADDR_IPX 
//    with relevant address-family, network number, node number 
//    and socket (endpoint) parameters.
//
void FillIpxAddress(SOCKADDR_IPX *psa, LPSTR lpsAddress, LPSTR lpsEndpoint)
{
    LPSTR pszPoint;                 
  
    ZeroMemory(psa, sizeof(SOCKADDR_IPX));
        
    psa->sa_family = AF_IPX;
    //
    // Check if an address is specified
    //
    if (lpsAddress != NULL)
    {
        //
        // Get the offset for node number/network number separator
        //
        pszPoint = strchr(lpsAddress, '.');

        if (pszPoint == NULL)
        {
            printf("IPX address does not have a separator\n");
            ExitProcess(-1);
        }
        // convert the address in the  string format to binary format
        //
        AtoH((CHAR *)psa->sa_netnum,  lpsAddress, 4);
        AtoH((CHAR *)psa->sa_nodenum, pszPoint + 1, 6);
    }
    if (lpsEndpoint != NULL)
    {
        psa->sa_socket = (USHORT)atoi(lpsEndpoint);
    }
    return;
}

//
// Function: BindSocket
//
// Description:
//    BindSocket() binds the global socket descriptor 'sock' to 
//    the specified address. If an endpoint is specified it uses 
//    that or it binds to a system  assigned port.
//
void BindSocket(SOCKADDR_IPX *psa, LPSTR lpsAddress, LPSTR lpsEndpoint)
{
    int ret;

    // Fill the givenSOCKADDR_IPX structure
    //
    FillIpxAddress(psa, lpsAddress, lpsEndpoint);

    ret = bind(sock, (SOCKADDR *) psa, sizeof (SOCKADDR_IPX));
    if (ret == SOCKET_ERROR)
    {
        printf("bind() failed: %d\n", WSAGetLastError());
        return;
    }
    // Print the address we are bound to. If a particular interface is not
    // mentioned in the BindSocket() call, this may print the address as
    // 00000000.0000000000000000. This is because of the fact that an 
    // interface is picked only when the actual connection establishment 
    // occurs, in case of connection oriented socket.
    //
    printf("Bound to Local Address - " );
    PrintIpxAddress(psa->sa_netnum, psa->sa_nodenum);
        
    return;
}

//
// Function: EnumerateAdapters
//
// Description:
//    EnumerateAdapters () will enumerate the available IPX adapters 
//    and print the addresses.
//
void EnumerateAdapters()
{
    SOCKADDR_IPX     sa_ipx;
    IPX_ADDRESS_DATA ipx_data;
    int              ret, 
                     cb, 
                     nAdapters, 
                     i=0;
        
    // Create a local socket
    //
    chProtocol = 'd';
    CreateSocket();
    //
    // Bind to a local address and endpoint
    //
    BindSocket ( &sa_ipx, NULL, NULL );
    //
    // Call getsockopt() see the total number of adapters
    //
    cb = sizeof(nAdapters);
    ret = getsockopt(sock, NSPROTO_IPX, IPX_MAX_ADAPTER_NUM,
        (CHAR *) &nAdapters, &cb);
    if (ret == SOCKET_ERROR)
    {
        printf("getsockopt(IPX_MAX_ADAPTER_NUM) failed: %d\n",
            WSAGetLastError());
        return;
    }
    printf("Total number of adapters -> %d\n", nAdapters);
    //
    // Get the address of each adapter
    //
    for(i=0; i < nAdapters ;i++)
    {                                                
        memset (&ipx_data, 0, sizeof(ipx_data));
        ipx_data.adapternum = i;
        cb = sizeof(ipx_data);
                        
        ret = getsockopt(sock, NSPROTO_IPX, IPX_ADDRESS, 
            (CHAR *) &ipx_data, &cb);
        if (ret == SOCKET_ERROR)
        {
            printf("getsockopt(IPX_ADDRESS) failed: %d\n",
                WSAGetLastError());
            return;
        }
        // Print each address
        //
        PrintIpxAddress(ipx_data.netnum, ipx_data.nodenum);
    }
    return;
}

//
// SendData() is generic rotuine to send some data over a 
// connection-oriented IPX socket.
//
int SendData(SOCKET s, char *pchBuffer)
{
    int ret;
        
    ret = send(s, pchBuffer, strlen(pchBuffer), 0);
    if (ret == SOCKET_ERROR)
    {
        printf("send() failed: %d\n", WSAGetLastError());
        return -1;
    }
    return ret;
}

//
// ReceiveData() is generic rotuine to receive some data over a 
// connection-oriented IPX socket.
//
int ReceiveData(SOCKET s, char *pchBuffer)
{
    int ret,
        iTotal=0,
        iLeft=dwNumBytes;
                
    while(iLeft > 0)
    {
        ret = recv(s, &pchBuffer[iTotal], iLeft, 0);
        if (ret == SOCKET_ERROR)
        {
            if (WSAGetLastError() == WSAEWOULDBLOCK)

⌨️ 快捷键说明

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