昨晚有个需求,局域网中,别人有个电脑客户端,发送UDP数据到本电脑。 但是我需要向整个局域网所有电脑广播数据,
于是参考WINDOWS UDP编程,整理了个测试代码。测试代码,有可能来源于网络,如有雷同,请联系本人。
VC建立一个CONSOLE工程,然后编译,运行即可. 同样,监听了CTR-C 事件,否则程序无法退出. MAX_BUFFER太小,
WINDOWS下 会报错。
UDPProxy.cpp
// UDPProxy.cpp :
//
#include
#include
#include
#include
#pragma comment(lib, "WS2_32.lib")
#define MAX_BUFFER 1024
BOOL mbCloseConsole = false;
SOCKET g_sendSock;
SOCKADDR_IN sendAddr_in;
BOOL CtrlHandler(DWORD fdwCtrlType)
{
switch (fdwCtrlType)
{
// Handle the CTRL-C signal.
case CTRL_C_EVENT:
printf("Ctrl-C even\n");
mbCloseConsole = true;
return(TRUE);
case CTRL_CLOSE_EVENT:
printf("Ctrl-Close event\n");
mbCloseConsole = true;
return(TRUE);
default:
return FALSE;
}
return TRUE;
}
int InitSendSocket()
{
g_sendSock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (INVALID_SOCKET == g_sendSock)
{
printf("g_sendSock failed with error: %d/n", WSAGetLastError());
WSACleanup();
return EXIT_FAILURE;
}
memset(&sendAddr_in, 0, sizeof(sendAddr_in));
sendAddr_in.sin_family = AF_INET;
sendAddr_in.sin_addr.S_un.S_addr = htonl(INADDR_BROADCAST);
sendAddr_in.sin_port = htons(3002);
BOOL bBoardcast = TRUE;
if (SOCKET_ERROR == setsockopt(g_sendSock, SOL_SOCKET, SO_BROADCAST, (char*)&bBoardcast, sizeof(bBoardcast)))
{
printf("g_sendSock setsockopt failed with error code: %d/n", WSAGetLastError());
if (INVALID_SOCKET != g_sendSock)
{
closesocket(g_sendSock);
g_sendSock = INVALID_SOCKET;
}
WSACleanup();
}
printf("g_sendSock Server start, start to boardcast .../n");
return 0;
}
int main(int argc, char* argv[])
{
WORD wVersionRequested = MAKEWORD(2, 2);
WSADATA wsaData;
mbCloseConsole = false;
if (0 != WSAStartup(wVersionRequested, &wsaData))
{
printf("WSAStartup failed with error: %d\n", GetLastError());
return EXIT_FAILURE;
}
if (2 != HIBYTE(wsaData.wVersion) || 2 != LOBYTE(wsaData.wVersion))
{
printf("Socket version not supported.\n");
WSACleanup();
return EXIT_FAILURE;
}
SOCKET recvSock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (INVALID_SOCKET == recvSock)
{
printf("socket failed with error: %d\n", WSAGetLastError());
WSACleanup();
return EXIT_FAILURE;
}
int nRecvBuf = 32 * 1024;
setsockopt(recvSock, SOL_SOCKET, SO_RCVBUF, (const char*)&nRecvBuf, sizeof(int));
int nSendBuf = 32 * 1024;
setsockopt(recvSock, SOL_SOCKET, SO_SNDBUF, (const char*)&nSendBuf, sizeof(int));
SOCKADDR_IN addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
addr.sin_port = htons(3001);
if (SOCKET_ERROR == bind(recvSock, (LPSOCKADDR)&addr, sizeof(addr)))
{
printf("bind failed with error: %d\n", WSAGetLastError());
if (INVALID_SOCKET != recvSock)
{
closesocket(recvSock);
recvSock = INVALID_SOCKET;
}
WSACleanup();
return EXIT_FAILURE;
}
char szBuf[MAX_BUFFER] = { 0 };
SOCKADDR_IN remote;
memset(&remote, 0, sizeof(remote));
int len = sizeof(remote);
InitSendSocket();
int nNetTimeout = 1000;
setsockopt(g_sendSock, SOL_SOCKET,SO_SNDTIMEO,(char *)&nNetTimeout,sizeof(int));
setsockopt(recvSock, SOL_SOCKET,SO_RCVTIMEO,(char *)&nNetTimeout,sizeof(int));
SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler, TRUE);
while (!mbCloseConsole)
{
int nRet = recvfrom(recvSock, szBuf, MAX_BUFFER - 1, 0, (LPSOCKADDR)&remote, &len);
if (SOCKET_ERROR == nRet)
{
printf("recvfrom failed with error: %d\n", WSAGetLastError());
continue;
}
printf("recv data: %d \n", nRet);
if (nRet > 0) {
int sendRet=sendto(g_sendSock, szBuf, nRet, 0, (LPSOCKADDR)&sendAddr_in, sizeof(sendAddr_in));
if (sendRet <=0 )
{
printf("sendto failed with error: %d/n", WSAGetLastError());
}
printf("send data: %d \n", sendRet);
}
Sleep(5);
}
closesocket(recvSock);
closesocket(g_sendSock);
recvSock = INVALID_SOCKET;
g_sendSock = INVALID_SOCKET;
WSACleanup();
return 0;
}