解决windows下UDP网络数据接收时recvfrom时返回值为 -1 但是缓冲区buffer有数据的问题

引言

最近在windows下编写UDP网络服务器,用于接收来自Linux开发板发送过来的数据,遇到返回值-1 但是接收buffer中数据完整,本文介绍调试过程以及在调试过程中思路和方法。

一 问题描述

windows作为UDP服务器端,Linux下作为客户端,windows下每次接收recvfrom接收的数据返回值都是-1,通过windows下Wireshark抓包发现程序已经完整的接收数据,并且在Linux下通过tcpdump下抓包同样也没有发现什么问题,打算通过在程序中打印errno值来解决此问题。

二 解决过程

windows下采用GetLastError()来获取errno,而Linux、VxWorks平台则通过C语言中全局变量errno来进行获取,切记获取之前先清零。代码如下:

// windows下
#include <windows.h>
printf("errno = %d\n",  GetLastError());

将此errno进行打印发现错误编号:10040 错误含义:
一个在数据报套接字上发送的消息大于内部消息缓冲器或其他一些网络限制,或该用户用于接收数据报的缓冲器比数据报小
接下来查找Linux下有关发送的sendto代码:

 char buffer [128] = "time req";
 socklen_t len = sizeof(struct sockaddr);
 int iret = sendto(client_fd, buffer,sizeof(buffer), 0,(struct sockaddr*)&ser_addr,len); 
 printf("iret %d \n",iret);

通过调试打印:iret = 9 也就是说只发送了9个字节,但是制定的长度确实 sizeof(buffer) = 128 个字节,因此出现了在windows写接收数据长度不对的问题,通过修改代码:

 char buffer [128] = "time req";
 socklen_t len = sizeof(struct sockaddr);
 int iret = sendto(client_fd, buffer,strlen(buffer) + 1, 0,(struct sockaddr*)&ser_addr,len); 
 printf("iret %d \n",iret);

这样就把问题解决了。

三 总结

Linux下错误errno获取办法

#include <string.h>
#include <errno.h>
extern int errno;
//使用前
errno = 0;
//执行语句
//错误打印
printf("errno %d err: %s\n",errno,strerror(errno));

相关函数可以查找man手册:man strerror man 3 errno perror等操作查看

VxWorks平台和Linux类似

windows 下GetLastError()使用方法
GetLastError function
System Error Codes
以及其他相关函数的使用可以查看相关文档

此外通过wireshark抓包也发现一些问题;

发现有大量的空字节数据,因此也能判断出可能发送数据的长度有问题

结束语

本文通过调试windows下UDP数据接收问题介绍了一些调试工具和调试方法特此分享

猜你喜欢

转载自blog.csdn.net/wanxuexiang/article/details/83341282