UDP 局域网广播包 WINDOWS 测试代码 收UDP数据,然后再转发出来 测试代码

昨晚有个需求,局域网中,别人有个电脑客户端,发送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;
}

 

 

你可能感兴趣的:(网络通讯)