📄 atalk.cpp
字号:
// Module Name: atalk.cpp
//
// 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.cpp 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\n");
// -z Zone AppleTalk zone\n");
// -t Type AppleTalk type name\n");
// -n Object AppleTalk object name\n");
// -c x Number of packets to send\n");
// -b x Buffer size to send\n");
// -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 "WindowsSockets"
#define DEFAULT_OBJECT "AppletalkApp"
// 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: atalk [-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)
{
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();
break;
case 's': // act as a sender
bSender = TRUE;
break;
case 'z': // zone name
if(i+1 < argc)
{
strcpy(szZone,argv[i+1]);
++i;
}
break;
case 't': // type name
if(i+1 < argc)
{
strcpy(szType,argv[i+1]);
++i;
}
break;
case 'n': // object name
if(i+1 < argc)
{
strcpy(szObject,argv[i+1]);
++i;
}
break;
case 'c': // number of packets to send
if(i+1 < argc)
{
dwCount = atoi(argv[i+1]);
++i;
}
break;
case 'b': // size of packet to send
if(i+1 < argc)
{
dwSendSize = atoi(argv[i+1]);
if(dwSendSize > MAX_BUFFER)
usage();
++i;
}
break;
case 'p': // protocol to use
if(i+1 < argc)
{
if(strlen(argv[i+1]) >= 3)
{
if(0 == _stricmp(argv[i+1],"adsp"))
{
iProto = ATPROTO_ADSP;
iSocketType = SOCK_STREAM;
} else if (0 == _stricmp(argv[i+1],"pap"))
{
iProto = ATPROTO_PAP;
iSocketType = SOCK_RDM;
}
}
++i;
}
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;
printf("Found %d names!\n", lpLookupName->NoTuples);
//
// 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;
printf("addr->sat_family = AF_APPLETALK\n");
printf("addr->sat_net = %d\n", addr->sat_net);
printf("addr->sat_node = %d\n", addr->sat_node);
printf("addr->sat_socket = %d\n", addr->sat_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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -