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

📄 atalk.c

📁 windows 网络编程。pdf文档
💻 C
📖 第 1 页 / 共 2 页
字号:
// Module Name: Atalk.c
//
// Description:
//    This sample illustrates how to use the AppleTalk PAP and ADSP
//    protocol. This sample either acts as a sender or receiver.  
//    If acting as the receiver use the -z -t and -n options to 
//    specify the zone, type, and object name of your receiver 
//    (server).  If acting as the sender specify the -s options 
//    and the -z -t and -n options refer to the name of the 
//    AppleTalk endpoint to connect to (i.e. the receiver).
//
// Compile:
//    cl -o Atalk Atalk.c wsock32.lib
//
// Command line parameters/options:
//    usage: atalk [-s] [-z:Zone] [-t:Type] [n:Object] [-c:x] [-b:x] [-p:str]
//       -s         Act as a sender
//       -z:Zone    AppleTalk zone
//       -t:Type    AppleTalk type name
//       -n:Object  AppleTalk object name
//       -c:x       Number of packets to send
//       -b:x       Buffer size to send
//       -p:str     Specifies protocol (PAP or ADSP)
//
#include <windows.h>
#include <winsock.h>
#include <atalkwsh.h>

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

#define DEFAULT_ZONE        "*"
#define DEFAULT_TYPE        "Windows Sockets"
#define DEFAULT_OBJECT      "Appletalk-App"

// The maximum size of a PAP message is 4096 bytes
//
#define MAX_BUFFER          4096
#define DEFAULT_COUNT       20
#define MAX_PROTO           32

BOOL bSender=FALSE;

char szZone[MAX_ENTITY],     // Zone to lookup
     szType[MAX_ENTITY],     // Type the object belongs to
     szObject[MAX_ENTITY];   // Appletalk object (name) to

DWORD dwSendSize=MAX_BUFFER, // Number of bytes to send
      dwCount=DEFAULT_COUNT; // Number of packets to send

int   iProto=ATPROTO_PAP,    // Protocol to use (PAP or ADSP)
      iSocketType=SOCK_RDM;  // Socket type of the given protocol
                             //   PAP  == SOCK_RDM while
                             //   ADSP == SOCK_STREAM

//
// Function: usage
//
// Description:
//    Print usage information and exit.
//
void usage()
{
    printf("usage: pap [-s] [-z:Zone] [-t:Type]"
		   " [n:Object] [-c:x] [-b:x]\n");
    printf("       -s            Act as a sender\n");
    printf("       -z:Zone       AppleTalk zone\n");
    printf("       -t:Type       AppleTalk type name\n");
    printf("       -n:Object     AppleTalk object name\n");
    printf("       -c:x          Number of packets to send\n");
    printf("       -b:x          Buffer size to send\n");
    printf("       -p:[adsp|pap] Protocol to use\n");
    ExitProcess(1);
}

//
// Function: ValidateArgs
//
// Description:
//    This function parses the command line arguments and sets 
//    several global variables based upon the supplied commands.
//
void ValidateArgs(int argc, char **argv)
{
    char szProtoBuff[MAX_PROTO];
    int  i;

    for(i = 1; i < argc; i++)
    {
        if ((argv[i][0] == '-') || (argv[i][0] == '/'))
        {
            switch (tolower(argv[i][1]))
            {
                case 's':            // act as a sender
                    bSender = TRUE;
                    break;
                case 'z':            // zone name
                    strcpy(szZone, &argv[i][3]);
                    break;
                case 't':            // type name
                    strcpy(szType, &argv[i][3]);
                    break;
                case 'n':            // object name
                    strcpy(szObject, &argv[i][3]);
                    break;
                case 'c':            // number of packets to send
                    dwCount = atoi(&argv[i][3]);
                    break;
                case 'b':            // size of packet to send
                    dwSendSize = atoi(&argv[i][3]);
                    if (dwSendSize > MAX_BUFFER)
                        usage();
                    break;
                case 'p':            // protocol to use
                    if (strlen(argv[i]) > 3)
                    {
                        if (!stricmp(&argv[i][3], "adsp"))
                        {
                            iProto = ATPROTO_ADSP;
                            iSocketType = SOCK_STREAM;
                        }
                        else if (!stricmp(&argv[i][3], "pap"))
                        {
                            iProto = ATPROTO_PAP;
                            iSocketType = SOCK_RDM;
                        }
                    }
                    break;
                default:
                    usage();
                    break;
            }

        }
    }
    return;
}

//
// Function: RegisterName
//
// Description:
//    Register an AppleTalk name on the network
//
int RegisterName(SOCKET s, char *zone, char *type, char *obj)
{
    WSH_NBP_NAME  nbpname;
    int           ret;

    // Fill out the WSH_NBP_NAME structure
    //
    ZeroMemory(&nbpname, sizeof(nbpname));
    lstrcpy(nbpname.ZoneName, zone);
    nbpname.ZoneNameLen = strlen(zone);
    lstrcpy(nbpname.TypeName, type);
    nbpname.TypeNameLen = strlen(type);
    lstrcpy(nbpname.ObjectName, obj);
    nbpname.ObjectNameLen = strlen(obj);

    printf("Registering: %s:%s@%s\n", obj, type, zone);

    ret = setsockopt(s, SOL_APPLETALK, SO_REGISTER_NAME,
                (char *)&nbpname, sizeof(nbpname));
    if (ret == SOCKET_ERROR)
    {
        printf("setsockopt(SO_REGISTER_NAME) failed: %d\n",
            WSAGetLastError());
        return 1;
    }
    return 0;
}

//
// Function: FindName
//
// Description:
//    Lookup a given name on the AppleTalk network so that we can
//    get the network, node, and socket number associated with it
//    in order to make a connection.
//
int FindName(SOCKET s, char *zone, char *type, char *obj, 
             SOCKADDR_AT *addr)
{
    char              szLookup[MAX_BUFFER],
                     *lpLookup;
    PWSH_LOOKUP_NAME  lpLookupName=NULL;
    int               size = MAX_BUFFER,
                      ret;
    PWSH_NBP_TUPLE    lpTuple;

    lpLookupName = (PWSH_LOOKUP_NAME)szLookup;
    //
    // Fill in our WSH_LOOKUP_NAME structure with the name to find
    //
    strcpy(lpLookupName->LookupTuple.NbpName.ObjectName, obj);
    lpLookupName->LookupTuple.NbpName.ObjectNameLen = strlen(obj);
    strcpy(lpLookupName->LookupTuple.NbpName.TypeName, type);
    lpLookupName->LookupTuple.NbpName.TypeNameLen = strlen(type);
    strcpy(lpLookupName->LookupTuple.NbpName.ZoneName, zone);
    lpLookupName->LookupTuple.NbpName.ZoneNameLen = strlen(zone);

    ret = getsockopt(s, SOL_APPLETALK, SO_LOOKUP_NAME, 
                (char *)szLookup, &size);
    if (ret == SOCKET_ERROR)
    {
        printf("getsockopt() failed; %d\n", WSAGetLastError());
        return 1;
    }
    lpLookup = (char *)szLookup + sizeof(WSH_LOOKUP_NAME);
    lpTuple  = (PWSH_NBP_TUPLE)lpLookup;
    //
    // Note that we only return the first name returned
    // 
    addr->sat_family = AF_APPLETALK;
    addr->sat_net = lpTuple[0].Address.Network;
    addr->sat_node = lpTuple[0].Address.Node;
    addr->sat_socket = lpTuple[0].Address.Socket;

    return 0;
}

//
// Function: atalkrecv
// 
// Description:
//    On a socket read as much data as there is pending. For the PAP
//    protocol this means reading until WSARecvEx() returns without
//    the MSG_PARTIAL flag set. For ADSP we simply request to read
//    the maximum buffer size. If an error occurs we return the 
//    Winsock error; otherwise a zero is returned. For ADSP we are
//    assuming that the message from can be read on the first
//    attempt. 
//
int atalkrecv(SOCKET s, char *recvbuff, int *nRead)
{
    int			  iFlags=0,
                  ret;
    DWORD         dwErr;
    BOOL          bDone=FALSE;
    struct fd_set fdread;

    *nRead = 0;
    dwErr = 0;

    if (iProto == ATPROTO_PAP)
    {
        // For PAP we have to do a prime read first
        //
        ret = setsockopt(s, SOL_APPLETALK, SO_PAP_PRIME_READ,
                 recvbuff, MAX_BUFFER);
        if (ret == SOCKET_ERROR)
        {
            printf("setsockopt() failed: %d\n", 
                (dwErr = WSAGetLastError()));
            return dwErr;
        }
    }

    FD_ZERO(&fdread);
    FD_SET(s, &fdread);
    select(0, &fdread, NULL, NULL, NULL);

    while (!bDone)
    {
        // Make sure we receive the whole message (PAP only)
        //  For the ADSP protocol, WSARecvEx() will never
        //  return the MSG_PARTIAL flag
        //
        if ((ret = WSARecvEx(s, &recvbuff[(*nRead)], 
            MAX_BUFFER, &iFlags)) == SOCKET_ERROR)
        {
            if ((dwErr = WSAGetLastError()) == WSAEWOULDBLOCK)
                break;
            else if (dwErr == WSAENOTCONN)
                break;
            printf("WSARecvEx() failed: %d\n", dwErr);
            return dwErr;
        }
        if (ret == 0)
        {
            printf("graceful close\n");
            break;
        }
        if ((iFlags & MSG_PARTIAL) == 0)
            bDone = TRUE;
        (*nRead) += ret;

⌨️ 快捷键说明

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