2017-07-15 22 views
-1

1つのプログラム(特定のX-Plane 10)からデータを受信しようとしています。これはUDP接続によって行われるはずです。 XPlaneが送信するデータのフォーマットは、(4 + n * 32)バイトのパッケージです(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; 
} 

私は受け付けておりすべてがDATA @ +時々ランダムなシンボルです。

データグラムの最初の5バイトが「DATA @」であることがわかっているので、接続していても多かれ少なかれ動作していますが、Xplaneが送信している残りのデータを読み取らない理由はわかりません。

編集: 私は1つのコードをオンラインで見つけました。私はプログラムで使用しました。同じ結果: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); 

これは\0バイトで終了Cスタイルの文字列を取得する予定でC形式の関数です。

示されたコードは、このpackageバッファにnewを割り当て、このバッファをクリアまたは初期化できません。したがって、packageの最初の内容はランダムなごみです。図示コードは、バッファ内の一部のデータを受信する。

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

recvfrom()を受信した実際のバイト数を返すが、図示のコードは完全にそれを無視します。従って、実際に受け取られたものは、packageに入れられ、packageバッファの残りの部分には、最初に含まれていたランダムなごみがまだ含まれています。

受信パケットの最後のバイトの後ろに\0が正しく付加されているコードはありません。結果として、示されたコードがprintfpackageポインタにしようとすると、実際の内容はrecvfrom()になります。printfは、無駄なゴミがバッファに入っていて、そこに何か\0があります。

+0

Xplaneによって送信されるすべてのパケットはヌルで終了します。 私は 'pack'を0やその他の値で埋めようとしていました。そして、' recvfrom() 'を実行した後、それらのゼロまたは他の値を出力しませんが、同じ結果を返します。 – dwid

+0

@dwidそして、 ?たとえば、単に送信するだけではありません。 'strlen(...)'バイトではなく 'strlen(...)+ 1'ですか? –

+0

私は確信していないと言わなければならない... このデータをPythonで取得するための別の簡単なアプリを書いた。値をintに変換した後にそれが得られます。 メッセージを受け取りました:[68. 65. 84. 65. 64. 3. 0. 0. 0. 96. 111. 63. 65. 1. 253. 66. 65 205. 252. 66. 65. 216. 164. 66. 65. 0 192. 121. 196. 175. 76. 92. 65. 59. 99. 96. 65.60. 99. 96. 65 。] – dwid

関連する問題