vc编程中UDP通信服务端 recvfrom 函数问题

7 篇文章 0 订阅
2 篇文章 0 订阅

如何在UDP通信中的服务端和客户端 设置监听接收函数
recvfrom函数链接地址和端口, 都不是同局域网内地址,而是其他随机地址,具体原因排查后才真相大白!

之前第一版的代码中,设计由下位机为服务端,上位机软件只设置接收函数,点对点链接到服务端就可以。
最近更新的一版下位机程序,更换到FPGA处理,硬件工程师说是借用了其他的网络通信模块,下位机只设置了数据发送功能和通信端口+地址,结果第一版的上位机软件就读不到数据了。

原示例程序是可以接收下位机上报数据的,这就很纳闷了,费解啊 🥴😵😵‍💫🤯🤯

从网上找了个例子,关键代码如下:

WORD wVersionRequested = MAKEWORD(1, 1);
	WSADATA	 wsaData;
	int err = WSAStartup(wVersionRequested, &wsaData);
	if (err != 0)
	{
		std::string info = "WSASTAER FAILED WITH ERROR : ";
		info = info.append(std::to_string(err));
		OutputDebugStringA(info.c_str());
		AfxMessageBox(CString(info.c_str()));
		return;
	}

	if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)
	{
		std::string info = "COULD NOT FIND A USABLE VERSION OF WINSOCK.DLL";
		OutputDebugStringA(info.c_str());
		AfxMessageBox(CString(info.c_str()));
		WSACleanup();
		return;
	}
	else
	{
		std::string info = "THE WINSOCK.DLL 2.2 WAS FOUND OKAY";
		OutputDebugStringA(info.c_str());
	}

	sockSrv = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); //创建一个socket句柄;
	if (sockSrv == INVALID_SOCKET)
	{
		std::string info = "SOCKET FAILED WITH ERROR : ";
		info = info.append(std::to_string(WSAGetLastError()));
		OutputDebugStringA(info.c_str());
		AfxMessageBox(CString(info.c_str()));
		return;
	}
		
	CString csport;
	GetDlgItem(IDC_ETPORT)->GetWindowTextW(csport);
	USHORT dwport = atoi(CT2A(csport));

	SOCKADDR_IN  addrServ;
	memset(&addrServ, 0, sizeof(addrServ));
	addrServ.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
	addrServ.sin_family = AF_INET;
	addrServ.sin_port = htons(dwport);

	struct timeval tv;
	tv.tv_sec = 1;
	tv.tv_usec = 0;
	setsockopt(sockSrv, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv));
		
	auto ret = bind(sockSrv, (SOCKADDR*)&addrServ, sizeof(SOCKADDR));
	if (ret == SOCKET_ERROR)
	{
		std::string info = "BIND FAILED WITH ERROR : ";
		info = info.append(std::to_string(WSAGetLastError()));
		OutputDebugStringA(info.c_str());
		AfxMessageBox(CString(info.c_str()));
		return;
	}
		
	bRunning = true;

	GetDlgItem(IDC_BTSTART)->EnableWindow(FALSE);
	GetDlgItem(IDC_BTSTOP)->EnableWindow(TRUE);
	GetDlgItem(IDC_BTSEND)->EnableWindow(TRUE);

	thid = std::thread(&GetDataThread, this);
	thid.detach();
void GetDataThread()
{
	int length = sizeof(SOCKADDR);
	
	while (bRunning == true)
	{
		char recvBuf[100] = { 0 };
		int len = recvfrom(sockSrv, recvBuf, 100, 0, (SOCKADDR*)&(addrClient), &length);
		if (len <= 0 || std::string(recvBuf).length() <= 0)
		{
			Sleep(10);
			continue;
		}		
		PrintToList(CString(recvBuf), true);
		OutputDebugStringA(recvBuf);

		Sleep(10);
	}
}

1、链接时 设置了监听函数,对任意地址和固定端口,来的数据都能监听接收在这里插入图片描述

在这里插入图片描述

2、问题来了:recvfrom 接收到的端口和地址 都是随机的,每次软件重新打开都会有数据过来,但不是局域网下位机主动上报的数据

在这里插入图片描述
断点后,查看参数 (SOCKADDR*)&(addrClient) ,地址和端口始终不对。

3、解决

再原有的代码上修改后,始终存在这个问题,后续把处理上报数据的函数搬运到 示例程序中,仍然不可以。

最笨的办法:代码一点点注释,恢复成原有代码,才发现问题

第一版代码中引用了 vector,然后 using namespace std,注释掉就能正确接收下位机地址端口数据,但是百思不得姐😕

网络上也没找到相关的问题资料,有哪位遇到过或者懂的能解释下不, 这里先感谢各位大佬的解答和回复。

我是逃逸的卡路里,希望遇到的问题解答,对你有帮助。

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

逃逸的卡路里

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值