📄 bclient.cpp
字号:
// send three zero byte datagrams.
if (gProtocol == IPPROTO_TCP)
{
shutdown(s, SD_SEND);
}
else
{
for(i=0; i < 3 ;i++)
{
rc = sendto(
s,
buf,
0,
0,
gConnectedEndpoint->ai_addr,
gConnectedEndpoint->ai_addrlen
);
}
}
// Free the send buffer
HeapFree(GetProcessHeap(), 0, buf);
ExitThread(0);
return 0;
}
//
// Function: ReceiveThread
//
// Description:
// This is the receive thread that attempts to receive all data on
// a given socket. For TCP this is done until the socket is closed
// (and the recv call returns an error or 0). For UDP, receives
// are performed until a zero byte datagram is received.
//
DWORD WINAPI ReceiveThread(LPVOID lpParam)
{
SOCKET s;
char *buf=NULL;
int buflen=0,
rc;
s = (SOCKET) lpParam;
// Allocate the receive buffer for this socket
buflen = gBufferSize;
buf = (char *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BYTE) * buflen);
if (buf == NULL)
{
fprintf(stderr, "ReadThread: HeapAlloc failed: %d\n", WSAGetLastError());
ExitProcess(-1);
}
while (1)
{
if (gProtocol == IPPROTO_UDP)
{
SOCKADDR_STORAGE addr;
int addrlen;
addrlen = sizeof(addr);
rc = recvfrom(
s,
buf,
buflen,
0,
(SOCKADDR *)&addr,
&addrlen
);
}
else if (gProtocol == IPPROTO_TCP)
{
rc = recv(
s,
buf,
buflen,
0
);
}
if ((rc == SOCKET_ERROR) || (rc == 0))
{
// Either a zero byte datagram was read (UDP), the connection was
// gracefully closed (TCP), or an error occured on the recv
break;
}
else
{
InterlockedExchangeAdd(&gBytesRead, rc);
}
}
// Free the receive buffer
HeapFree(GetProcessHeap(), 0, buf);
ExitThread(0);
return 0;
}
//
// Function: main
//
// Description:
// This is the main program. It parses the command line and creates
// the main socket. For UDP this socket is used to receive datagrams.
// For TCP the socket is used to accept incoming client connections.
// Each client TCP connection is handed off to a worker thread which
// will receive any data on that connection until the connection is
// closed.
//
int __cdecl main(int argc, char **argv)
{
WSADATA wsd;
SOCKET s;
HANDLE hThreads[2];
int rc; // return code
struct addrinfo *reslocal=NULL,
*resremote=NULL,
*ptr=NULL;
// Parse the command line
ValidateArgs(argc, argv);
// Load Winsock
if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
{
fprintf(stderr, "unable to load Winsock!\n");
return -1;
}
// Resolve the server's name
resremote = ResolveAddress(gServerAddr, gBindPort, gAddressFamily, gSocketType, gProtocol);
if (resremote == NULL)
{
fprintf(stderr, "ResolveAddress failed to return any addresses!\n");
return -1;
}
// Iterate through each address resolved from the server's name
ptr = resremote;
while (ptr)
{
printf("Local address: %s; Port: %s; Family: %d\n",
gBindAddr, gBindPort, gAddressFamily);
// Resolve the local address to bind to
reslocal = ResolveAddress(gBindAddr, "0", ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
if (reslocal == NULL)
{
fprintf(stderr, "ResolveAddress failed to return any addresses!\n");
return -1;
}
PrintAddress(reslocal->ai_addr, reslocal->ai_addrlen); printf("\n");
// create the socket
s = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
if (s == INVALID_SOCKET)
{
fprintf(stderr, "socket failed: %d\n", WSAGetLastError());
return -1;
}
// bind the socket to a local address and port
rc = bind(s, reslocal->ai_addr, reslocal->ai_addrlen);
if (rc == SOCKET_ERROR)
{
fprintf(stderr, "bind failed: %d\n", WSAGetLastError());
return -1;
}
// free the addrinfo structure for the 'bind' address
freeaddrinfo(reslocal);
if ((gProtocol == IPPROTO_TCP) || (bUdpConnect))
{
rc = connect(s, ptr->ai_addr, ptr->ai_addrlen);
if (rc == SOCKET_ERROR)
{
printf("connect failed: %d\n", WSAGetLastError());
closesocket(s);
s = INVALID_SOCKET;
}
else
{
break;
}
}
else
{
// Option is UDP with no connect, just take first address and go with it
break;
}
// move to the next address resolved
ptr = ptr->ai_next;
}
// See if we've got a good connection
if (s == INVALID_SOCKET)
{
fprintf(stderr, "Unable to connect to server via resolved address(es)\n");
return -1;
}
gConnectedEndpoint = ptr;
gStartTime = GetTickCount();
// Create the sending thread
hThreads[0] = CreateThread(NULL, 0, SendThread, (LPVOID)s, 0, NULL);
if (hThreads[0] == NULL)
{
fprintf(stderr, "CreateThread failed: %d\n", GetLastError());
return -1;
}
hThreads[1] = CreateThread(NULL, 0, ReceiveThread, (LPVOID)s, 0, NULL);
if (hThreads[1] == NULL)
{
fprintf(stderr, "CreateThread failed: %d\n", GetLastError());
return -1;
}
while (1)
{
rc = WaitForMultipleObjects(2, hThreads, TRUE, 5000);
if (rc == WAIT_FAILED)
{
}
else if (rc == WAIT_TIMEOUT)
{
ULONG bps, tick, elapsed;
tick = GetTickCount();
elapsed = (tick - gStartTime) / 1000;
bps = gBytesRead / elapsed;
printf("bytes per second read: %lu\n", bps);
bps = gBytesSent / elapsed;
printf("bytes per second sent: %lu\n", bps);
}
else
{
break;
}
}
CloseHandle(hThreads[0]);
CloseHandle(hThreads[1]);
freeaddrinfo(resremote);
closesocket(s);
printf("\n");
printf("total bytes sent %lu\n", gBytesSent);
printf("total bytes read %lu\n", gBytesRead);
WSACleanup();
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -