📄 atalk.c
字号:
}
return dwErr;
}
//
// Function: atalksend
//
// Description:
// Send the specified number of bytes from the buffer on the
// given socket. Nothing special needs to be done for either
// ADSP or PAP. For PAP, the message should only require one
// send. For ADSP, it could require several send() calls as
// it is stream oriented.
//
int atalksend(SOCKET s, char *sendbuf, int nSend)
{
DWORD dwErr;
int ret,
nPos;
struct fd_set fdwrite;
dwErr = 0;
FD_ZERO(&fdwrite);
FD_SET(s, &fdwrite);
select(0, NULL, &fdwrite, NULL, NULL);
nPos = 0;
while (nSend > 0)
{
if ((ret = send(s, &sendbuf[nPos], nSend, 0))
== SOCKET_ERROR)
{
if ((dwErr = WSAGetLastError()) != WSAEWOULDBLOCK)
{
printf("send() failed; %d\n", dwErr);
}
return dwErr;
}
nSend -= ret;
nPos += ret;
}
return dwErr;
}
//
// Function: ClientThread
//
// Description:
// A desc goes here
//
DWORD WINAPI ClientThread(LPVOID lpParam)
{
SOCKET s = (SOCKET)lpParam;
SOCKADDR_AT ataddr;
char recvbuff[MAX_BUFFER];
int nRead=0,
i,
optval=1,
ret;
// Make the socket non-blocking, error notification is easier
// this way
//
if (ioctlsocket(s, FIONBIO, &optval) == SOCKET_ERROR)
{
printf("ioctlsocket(FIONBIO) failed; %d\n",
WSAGetLastError());
return 1;
}
// For PAP, receive and send the requested number of packets.
// For ADSP, receive and send until the client closed the
// connection.
//
i = 0;
do {
if ((ret = atalkrecv(s, recvbuff, &nRead)) != 0)
{
if (ret == WSAEWOULDBLOCK)
{
printf("huh?\n");
continue;
}
else if (ret == WSAENOTCONN)
break;
else
{
printf("recv() failed: %d\n", ret);
break;
}
}
i++;
if (nRead > 0)
printf("read %d bytes\n", nRead);
if ((ret = atalksend(s, recvbuff, nRead)) != 0)
{
if (ret == WSAEWOULDBLOCK)
{
printf("duh?\n");
continue;
}
else
{
printf("send() failed: %d\n", ret);
break;
}
}
printf("wrote %d bytes\n", nRead);
} while (((i <= dwCount) && (iProto == ATPROTO_PAP)) ||
(iProto == ATPROTO_ADSP));
return 0;
}
//
// Function: main
//
// Description:
// Load the Winsock library, parse the command line arguments,
// create a socket of the requested type, and either send or
// receive data. For the PAP protocol make sure we receive
// an entire message by checking for the MSG_PARTIAL flag on
// return from WSARecvEx(). For ADSP, the receiver will
// continually loop until the connection is closed (as it is
// a stream protocol).
//
int main(int argc, char **argv)
{
WSADATA wsd;
SOCKET s;
SOCKADDR_AT ataddr;
int ret,
nRead,
ataddrsz = sizeof(ataddr);
DWORD dwErr;
strcpy(szZone, DEFAULT_ZONE);
strcpy(szType, DEFAULT_TYPE);
strcpy(szObject, DEFAULT_OBJECT);
//
// Get things started by validating command line args,
// loading the Winsock lib, and creating a socket of
// the requested type.
//
ValidateArgs(argc, argv);
if (WSAStartup(MAKEWORD(1,1), &wsd) != 0)
{
printf("WSAStartup failed!\n");
return 1;
}
s = socket(AF_APPLETALK, iSocketType, iProto);
if (s == INVALID_SOCKET)
{
printf("socket() failed: %d\n", WSAGetLastError());
return 1;
}
// Open a port on the AppleTalk network
//
ZeroMemory(&ataddr, sizeof(ataddr));
ataddr.sat_family = AF_APPLETALK;
ataddr.sat_socket = 0;
if (bind(s, (SOCKADDR *)&ataddr, sizeof(ataddr))
== INVALID_SOCKET)
{
printf("bind() failed: %d\n", WSAGetLastError());
return 1;
}
if (bSender) // we are sending packets
{
SOCKADDR_AT ataddr;
char sendbuff[MAX_BUFFER];
int i,
optval=1;
// Find the given name on the AppleTalk network so we can
// connect and send data to it!
//
if (FindName(s, szZone, szType, szObject, &ataddr) != 0)
{
printf("Unable to find receiver!\n");
return 1;
}
// If we found a name, try to connect to it
//
printf("Connecting to: %s:%s@%s\n",
szObject, szType, szZone);
if (connect(s, (SOCKADDR *)&ataddr,
sizeof(ataddr)) == SOCKET_ERROR)
{
printf("connect() failed: %d\n", WSAGetLastError());
return 1;
}
if (ioctlsocket(s, FIONBIO, &optval) == SOCKET_ERROR)
{
printf("ioctlsocket(FIONBIO) failed: %d\n",
WSAGetLastError());
return 1;
}
// Once we've connected, start sending data. Send the
// requested number of packets of the given size.
//
memset(sendbuff, 'a', dwSendSize);
i=0;
do {
if ((ret = atalksend(s, sendbuff, dwSendSize)) != 0)
{
if (ret == WSAEWOULDBLOCK)
{
printf("Client would block send\n");
continue;
}
else
{
printf("send() failed: %d\n", ret);
break;
}
}
i++;
printf("Wrote %d bytes\n", dwSendSize);
if ((ret = atalkrecv(s, sendbuff, &nRead)) != 0)
{
if (ret == WSAEWOULDBLOCK)
{
printf("Client would block recv\n");
continue;
}
else
{
printf("recv() failed: %d\n", ret);
break;
}
}
printf("Read %d bytes\n", nRead);
} while (i < dwCount);
}
else // We're receiving data
{
SOCKET scli;
BOOL bDone=FALSE;
HANDLE hThread;
DWORD dwThreadId;
struct fd_set fdread;
// Register our name so others can connect to it
//
if (RegisterName(s, szZone, szType, szObject) != 0)
return 1;
listen(s, 8);
while (!bDone)
{
FD_ZERO(&fdread);
FD_SET(s, &fdread);
select(0, &fdread, NULL, NULL, NULL);
//
// Once we receive a connection accept it
//
scli = accept(s, (SOCKADDR *)&ataddr, &ataddrsz);
if (scli == INVALID_SOCKET)
{
printf("accept() failed: %d\n", WSAGetLastError());
bDone = TRUE;
}
hThread = CreateThread(NULL, 0, ClientThread, (LPVOID)scli,
0, &dwThreadId);
if (hThread == NULL)
{
printf("CreateThread() failed: %d\n", GetLastError());
bDone = TRUE;
}
CloseHandle(hThread);
}
}
closesocket(s);
WSACleanup();
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -