2017-07-15 68 views
-1

我試圖從一個程序接收數據(X-平面10是特異性的)。它應該由UDP連接完成。 XPlane發送數據的格式爲(4 + n * 32)字節包(n-取決於Xplane內的設置)。 我想通過下面的代碼來接受它:UDP客戶端(接收器)沒有接收到的數據報,因爲它應該

const int LEN = 256; 
int server_length; 
int port = 49010; 

char* package = new char[LEN]; 

WSADATA wsaData; 
SOCKET mySocket; 
SOCKET myBackup; 
SOCKET acceptSocket; 
sockaddr_in myAddress; 

int _tmain(int argc, _TCHAR* argv[]) 
{ 

//socket 
if(WSAStartup(MAKEWORD(2, 2), &wsaData) != NO_ERROR) 
{ 
    cerr<<"Socket Initialization: Error with WSAStartup\n"; 
    system("pause"); 
    WSACleanup(); 
    exit(10); 
} 

mySocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 

if (mySocket == INVALID_SOCKET) 
{ 
    cerr<<"Error creating socket"<<endl; 
    system("pause"); 
    WSACleanup(); 
    exit(11); 
} 


//binding 
myAddress.sin_family = AF_INET; 
myAddress.sin_addr.s_addr = inet_addr("127.0.0.1"); 
myAddress.sin_port = htons(port); 

if(bind(mySocket, (SOCKADDR*) &myAddress, sizeof(myAddress)) == SOCKET_ERROR) 
{ 
    cerr<<"Failed to connect\n"; 
    system("pause"); 
    WSACleanup(); 
    exit(14); 
} 

//receiving 
while (true) 
{ 
    cout.flush(); 
    server_length = sizeof(struct sockaddr_in); 
    myAddress.sin_port = htons(port); 
    recvfrom(mySocket, package, LEN, 0, (SOCKADDR*) &myAddress, &server_length); 
    printf("%s\n", package); 
} 
    return 0; 
} 

所有我收到的數據@ +有時隨機碼元。

我知道數據報的前5個字節應該是「DATA @」,所以我知道它正在連接,並且或多或少的工作,但我不明白爲什麼它不讀取由Xplane發送的其餘數據。

編輯: 我發現一個代碼在網上,我用它在我的計劃。同樣的結果:DATA @ ...

它不顯示任何其他文件中的任一。

#define DEFAULT_PORT   49010 
#define DEFAULT_COUNT   100 
#define DEFAULT_BUFFER_LENGTH 41 

int iPort = DEFAULT_PORT;   // Port to receive on 
DWORD dwCount = DEFAULT_COUNT,   // Number of messages to read 
dwLength = DEFAULT_BUFFER_LENGTH; // Length of receiving buffer 
BOOL bInterface = FALSE;    // Use an interface other than 
           // default 
char szInterface[32];   // Interface to read datagrams from 

// 
// Function: usage: 
// 
// Description: 
// Print usage information and exit 
// 
void usage() 
{ 
printf("usage: sender [-p:int] [-i:IP][-n:x] [-b:x]\n\n"); 
printf("  -p:int Local port\n"); 
printf("  -i:IP Local IP address to listen on\n"); 
printf("  -n:x  Number of times to send message\n"); 
printf("  -b:x  Size of buffer to send\n\n"); 
ExitProcess(1); 
} 

// 
// Function: ValidateArgs 
// 
// Description: 
// Parse the command line arguments, and set some global flags to 
// indicate what actions to perform 
// 
void ValidateArgs(int argc, char **argv) 
{ 
int    i; 

for(i = 1; i < argc; i++) 
{ 
    if ((argv[i][0] == '-') || (argv[i][0] == '/')) 
    { 
     switch (tolower(argv[i][1])) 
     { 
      case 'p': // Local port 
       if (strlen(argv[i]) > 3) 
        iPort = atoi(&argv[i][3]); 
       break; 
      case 'n': // Number of times to receive message 
       if (strlen(argv[i]) > 3) 
        dwCount = atol(&argv[i][3]); 
       break; 
      case 'b': // Buffer size 
       if (strlen(argv[i]) > 3) 
        dwLength = atol(&argv[i][3]); 
       break; 
      case 'i': // Interface to receive datagrams on 
       if (strlen(argv[i]) > 3) 
       { 
        bInterface = TRUE; 
       strcpy(szInterface, &argv[i][3]); 
       } 
       break; 
      default: 
       usage(); 
       break; 
     } 
    } 
} 
} 

// 
// Function: main 
// 
// Description: 
// Main thread of execution. Initialize Winsock, parse the command 
// line arguments, create a socket, bind it to a local interface 
// and port, and then read datagrams. 
// 
int main(int argc, char **argv) 
{ 
WSADATA  wsd; 
SOCKET   s; 
char   *recvbuf = NULL; 
int   ret, 
       i; 
int   dwSenderSize; 
SOCKADDR_IN sender, 
       local; 

// Parse arguments and load Winsock 
// 
ValidateArgs(argc, argv); 

if (WSAStartup(MAKEWORD(2,2), &wsd) != 0) 
{ 
    printf("WSAStartup failed!\n"); 
    return 1; 
} 
// Create the socket and bind it to a local interface and port 
// 
s = socket(AF_INET, SOCK_DGRAM, 0); 
if (s == INVALID_SOCKET) 
{ 
    printf("socket() failed; %d\n", WSAGetLastError()); 
    return 1; 
} 
local.sin_family = AF_INET; 
local.sin_port = htons((short)iPort); 
if (bInterface) 
    local.sin_addr.s_addr = inet_addr(szInterface); 
else 
    local.sin_addr.s_addr = htonl(INADDR_ANY); 
if (bind(s, (SOCKADDR *)&local, sizeof(local)) == SOCKET_ERROR) 
{ 
    printf("bind() failed: %d\n", WSAGetLastError()); 
    return 1; 
} 
// Allocate the receive buffer 
// 
recvbuf = (char*)GlobalAlloc(GMEM_FIXED, dwLength); 
if (!recvbuf) 
{ 
    printf("GlobalAlloc() failed: %d\n", GetLastError()); 
    return 1; 
} 
// Read the datagrams 
// 

std::ofstream myfile; 
myfile.open ("file.txt"); 


for(i = 0; i < dwCount; i++) 
{ 
    dwSenderSize = sizeof(sender); 
    ret = recvfrom(s, recvbuf, dwLength, 0, 
     (SOCKADDR *)&sender, &dwSenderSize); 
    if (ret == SOCKET_ERROR) 
    { 
     printf("recvfrom() failed; %d\n", WSAGetLastError()); 
     break; 
    } 
    else if (ret == 0) 
     break; 
    else 
    { 
     recvbuf[ret] = '\0'; 
     printf("[%s] sent me: '%s'\n", 
      inet_ntoa(sender.sin_addr), recvbuf); 
     myfile << recvbuf<<endl; 
    } 
} 
closesocket(s); 

GlobalFree(recvbuf); 
WSACleanup(); 
myfile.close(); 
return 0; 
} 
+0

是「DATA @」二進制還是字符(可打印)數據之後的數據? –

+0

它是二進制數據 – dwid

+0

*總是*檢查從'recvfrom'(和類似函數)返回的值。它會告訴你收到的字節的確切數量,*和*如果有錯誤。除了'recvfrom'寫入緩衝區的數據之外,你需要檢查未初始化的和*不確定的*數據(除非你初始化整個緩衝區)並且這會導致*未定義的行爲*。 –

回答

0
printf("%s\n", package); 

這是C風格的函數,期望得到一個C風格的字符串,以\0字節結束。

所示出的代碼分配本package緩衝液new,並且不能清除或初始化該緩衝器。因此,package的初始內容是隨機垃圾。示出的代碼然後接收一些數據在緩衝器:

recvfrom(mySocket, package, LEN, 0, (SOCKADDR*) &myAddress, &server_length); 

recvfrom()返回接收到的字節的實際數目,但示出完全代碼忽略。因此,實際得到的任何內容都會被放入package,其餘的package緩衝區仍然包含前面提到的隨機垃圾,它最初包含在內。

沒有什麼中所示的代碼,在接收數據包的最後一個字節正確後追加一個\0。因此,當顯示的代碼嘗試指向printfpackage指針時,recvfrom()的實際內容將隨後是緩衝區中的任何隨機垃圾,直到printf通過抽獎的運氣找到某個\0,在某處。

+0

Xplane發送的每個數據包都是空終止的。 我一直在試圖填充在'package'零或其它值,它經過'recvfrom的後()'它好好嘗試打印這些零或其他calues,但仍然給出了同樣的結果 – dwid

+0

@dwid和發送者發送終止?它不僅僅發送例如'strlen(...)'字節,但'strlen(...)+ 1'? –

+0

我必須說我不知道​​... 我寫了另一個簡單的應用程序來獲取這些數據在Python中。這就是我在將值轉換爲int後得到的結果: 收到消息:[68. 65. 84. 65. 64. 3. 0.0 96. 111. 63. 65. 1. 253. 66. 65 205. 252. 66. 65. 216 46. 66. 65. 0.192. 121. 196. 175。76. 92. 65. 59. 99. 96. 65. 60. 99. 96. 65 。] – dwid

相關問題