📄 winsockserver.cpp
字号:
//****************************************************************************//
//* //
//* Copyright (C) 2003, James Antognini, antognini@mindspring.com. //
//* //
//****************************************************************************//
/**************************************************************************************************/
/* */
/* Adapted from */
/* ms-help://MS.MSDNQTR.2002JUL.1033/wcewinsk/htm/_wcecomm_TCP_Stream_Socket_Server.htm */
/* */
/**************************************************************************************************/
#define JAProgNm "WinsockServer"
#define JAProgVersion "1.43"
#include <winsock2.h>
#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <process.h>
#include <commctrl.h>
#include <winioctl.h>
#include "TDIClient.h"
int main(
IN int nbrArgs,
IN char * pArgv[]
)
{
static struct
{
DWORD CmdCode;
char * pInStr;
}
#define rcOK 0
#define rcError 8
#define CmdUnknown 0
#define CmdStart 1
#define CmdStop 2
#define CmdTest 3
#define CmdTest2 4
InStrArr[] =
{ // Except that CmdUnknown has to be first, the following can be in any order.
{CmdUnknown, ""},
{CmdTest, "Port"},
{CmdTest2, "."},
};
char static DateCompiledBase[] = __DATE__,
TimeCompiledBase[] = " " __TIME__,
dfltPort[] = // Default port.
charDfltPort;
#define CompDateTimeStr "dd mmm yyyy hh:mm:ss"
char szServerA[TDIClientRecvBfrLen],
DateCompiled[12] = // Build date in preferred (dd mmm yyyy) format.
{DateCompiledBase[4], DateCompiledBase[5], DateCompiledBase[6],
DateCompiledBase[0], DateCompiledBase[1], DateCompiledBase[2], DateCompiledBase[3],
DateCompiledBase[7], DateCompiledBase[8], DateCompiledBase[9], DateCompiledBase[10],
0x0
},
JAProgInfo[] = JAProgNm " v" JAProgVersion " (compiled ",
PgmCompiledInfo[sizeof(CompDateTimeStr)+1];
char static * pClientBoundMessage[] = {
"This is a first (1) message from the Winsock server v" JAProgVersion " (compiled ",
"This is a second (2) message from the Winsock server.",
"This is a third (3) message from the Winsock server.",
"This is a fourth (4) message from the Winsock server.",
"This is a fifth (5) message from the Winsock server."
};
char * pPort;
int rcRecv, // Return value of recv function
accept_sin_len, // Length of accept_sin
i,
port,
rc = rcOK,
lnInStrArr = // Get number of instances.
sizeof InStrArr / sizeof InStrArr[0],
TotalRecvd = 0,
CmdNbr = CmdUnknown;
BOOL bFirst = TRUE;
ULONG ulTotalSend; // Total number of bytes that will be sent.
SOCKET WinSocket = INVALID_SOCKET, // Window socket
ClientSock = INVALID_SOCKET; // Socket for communicating between the server and client
SOCKADDR_IN local_sin, // Local socket address
accept_sin; // Receives the address of the connecting entity
WSADATA WSAData; // Contains details of the Winsock implementation
#define MAX_PENDING_CONNECTS 4 // Maximum length of the queue of pending connections
if (' '==DateCompiled[0])
strcpy(PgmCompiledInfo, DateCompiled+1);
else
strcpy(PgmCompiledInfo, DateCompiled+0);
strcat(PgmCompiledInfo, TimeCompiledBase);
printf("%s%s)\n", JAProgInfo, PgmCompiledInfo);
if (nbrArgs>=2)
{
for (i = 1; i < lnInStrArr; i ++) // Go through expected parameters.
if (0==_stricmp(pArgv[1], InStrArr[i].pInStr)) // Does the second parm match?
break; // If yes, break.
}
else
i = lnInStrArr; // Ensure next conditional yields supported parameter information.
if (i<lnInStrArr) // Found a supported command?
CmdNbr = InStrArr[i].CmdCode;
else
{
printf("\nUnsupported command\n\n");
printf("Usage: " JAProgNm " <operand>\n\n");
printf(" where <operand> is one of these:\n\n");
for (i = 1; i < lnInStrArr; i ++)
printf(" %s\n", InStrArr[i].pInStr);
printf("\n Eg,\n\n <Port <port | .> | .>\n");
printf("\n (Capitalization is ignored.)\n");
printf("\n (Default: Port = %s.)\n", dfltPort);
rc = 1;
goto ExitPoint;
}
if (3==nbrArgs)
{
pPort = pArgv[2]; // Get port.
if (0==strcmp(pPort, ".")) // Dot given?
pPort = dfltPort; // Point to default port.
}
else
pPort = dfltPort; // Get port.
port = atoi(pPort); // Convert ascii to integer.
printf(" Using port = %d\n\n", port);
// Initialize Winsock.
if (WSAStartup(MAKEWORD(2,0), &WSAData) != 0) // Accept up to Winsock 2.0.
{
printf(JAProgNm ": WSAStartup failed. Error = %d\n", WSAGetLastError());
return 1;
}
// Create a TCP/IP socket, WinSocket.
if ((WinSocket = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
{
printf(JAProgNm ": Allocating socket failed. Error = %d\n", WSAGetLastError());
return 1;
}
// Fill out the local socket's address information.
local_sin.sin_family = AF_INET;
local_sin.sin_port = htons(port);
local_sin.sin_addr.s_addr = htonl(INADDR_ANY);
// Associate the local address with WinSocket.
if (bind(WinSocket,
(struct sockaddr *) &local_sin,
sizeof (local_sin)) == SOCKET_ERROR)
{
printf(JAProgNm ": Binding socket failed. Error = %d\n", WSAGetLastError());
closesocket(WinSocket);
return 1;
}
// Establish a socket to listen for incoming connections.
if (listen(WinSocket, MAX_PENDING_CONNECTS) == SOCKET_ERROR)
{
printf(JAProgNm ": Listening to the client failed. Error = %d\n", WSAGetLastError());
closesocket (WinSocket);
return 1;
}
accept_sin_len = sizeof(accept_sin);
// Accept an incoming connection attempt on WinSocket.
ClientSock = accept(WinSocket,
(struct sockaddr *) &accept_sin,
(int *) &accept_sin_len
);
// Stop listening for connections from clients.
closesocket(WinSocket);
if (INVALID_SOCKET==ClientSock)
{
printf(JAProgNm ": Accepting connection with client failed. Error = %d\n", WSAGetLastError());
return 1;
}
// Behavior: 1) receive loop;
// 2) send loop.
for (;;) // Receive loop, until 0 bytes received.
{
// Receive data from the client.
rcRecv = recv(ClientSock, szServerA, sizeof(szServerA), 0);
// Check if there are any data received. If there are, display them.
if (SOCKET_ERROR==rcRecv)
{
printf(JAProgNm ": No data is received, recv failed. Error = %d\n", WSAGetLastError());
break;
}
else if (0==rcRecv) // Connection gracefully closed?
{
printf(JAProgNm ": Finished receiving data\n");
break;
}
else
{
TotalRecvd += rcRecv; // Accumulate total received.
// printf(JAProgNm ": Received %d bytes from client\n", rcRecv);
#define ClientMsgArraySz 10
// It is assumed -- but not checked -- that in each receive there is at least 1 string and
// that the total number of strings sent across receives does not exceed ClientMsgArraySz.
char * pClnMsg[ClientMsgArraySz];
int msgCt = 0;
BOOLEAN bFindNextStr = TRUE;
// Find strings (there may be more than one in the received data).
for (int charIdx = 0; charIdx < rcRecv; charIdx ++)
{
if (TRUE==bFirst) // First string?
{
charIdx += sizeof(ULONG); // Bump past total byte count.
bFirst = FALSE; // Turn off flag.
}
if (TRUE==bFindNextStr) // Looking for a string?
if (0!=szServerA[charIdx]) // Is current byte not 0?
{
msgCt++; // Bump string count.
pClnMsg[msgCt-1] = // Point to current string.
&szServerA[charIdx];
bFindNextStr = FALSE; // Remember now not looking for a string.
}
else
;
else // Handling a string.
if (0==szServerA[charIdx]) // Is current byte 0?
bFindNextStr = TRUE; // Remember now looking for a string.
else
;
}
for (int msgIdx = 0; msgIdx < msgCt; msgIdx ++)
// Display the string(s) received from the client.
printf(JAProgNm ": Received from client = \n ***>>>%s<<<***\n", pClnMsg[msgIdx]);
}
} // End 'for' receive loop.
printf("\n" JAProgNm ": Total received from client = %d\n", TotalRecvd);
for ( // Add size of strings (including terminator), except for first.
i = 1,
ulTotalSend = 0;
i < arraysize(pClientBoundMessage);
i ++
)
ulTotalSend += strlen(pClientBoundMessage[i])+1;
// Send strings to the client.
for ( // Send loop.
i = 0;
i < arraysize(pClientBoundMessage);
i ++
)
{
char * pBuffer;
ULONG sendLn = strlen(pClientBoundMessage[i])+1; // Get size of current string, including terminator.
if (0==i) // First send?
{
sendLn += sizeof(ULONG) + // Add size of "header,"
strlen(PgmCompiledInfo) + // size of date/time compiled and
2; // size of closing parenthesis and period
pBuffer = (char *)malloc(sendLn); // Get a buffer.
if (NULL==pBuffer) // No good?
{
printf(JAProgNm ": Couldn't allocate buffer, quitting\n");
goto DoShutdown;
}
ulTotalSend += sendLn; // Add size of first string.
*(PULONG)pBuffer = ulTotalSend; // Copy total amount to be sent.
strcpy(pBuffer+sizeof(ULONG), // Copy string.
pClientBoundMessage[0]
);
strcat(pBuffer+sizeof(ULONG), // Append date/time compiled.
PgmCompiledInfo
);
strcat(pBuffer+sizeof(ULONG), ")."); // Append closing parenthesis and period.
printf("\n" JAProgNm ": About to send a total of %d bytes to client\n", ulTotalSend);
// printf(JAProgNm ": Sending %d bytes\n >%s<\n", sendLn, pBuffer+sizeof(ULONG));
}
else
pBuffer = pClientBoundMessage[i];
// printf(JAProgNm ": Sending %d bytes\n >%s<\n", sendLn, pBuffer);
int lclStatus = send(ClientSock,
pBuffer,
sendLn,
0
);
if (0==i) // First send?
free(pBuffer); // Free buffer.
if (SOCKET_ERROR==lclStatus)
{
printf(JAProgNm ": Sending data #%d to the client failed. Error = %d\n", i, WSAGetLastError());
}
else
{
// printf(JAProgNm ": Sent %d bytes to the client\n", lclStatus);
}
} // End 'for' send loop.
DoShutdown:
// Disable both sending and receiving on ClientSock.
shutdown(ClientSock, SD_BOTH);
// Close ClientSock.
closesocket(ClientSock);
WSACleanup();
ExitPoint:
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -