1. 程式人生 > >解決windows下UDP網路資料接收時recvfrom時返回值為 -1 但是緩衝區buffer有資料的問題

解決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資料接收問題介紹了一些除錯工具和除錯方法特此分享