我試圖從一個程序接收數據(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;
}
是「DATA @」二進制還是字符(可打印)數據之後的數據? –
它是二進制數據 – dwid
*總是*檢查從'recvfrom'(和類似函數)返回的值。它會告訴你收到的字節的確切數量,*和*如果有錯誤。除了'recvfrom'寫入緩衝區的數據之外,你需要檢查未初始化的和*不確定的*數據(除非你初始化整個緩衝區)並且這會導致*未定義的行爲*。 –