c++ 和 simulink 之间通过 udp 通信
communications between c++ and simulink via udp
我正在尝试让我的 c++ 程序通过 udp 与 simulink 模型进行通信,特别是计划将数据从 c++ 传输到 simulink,并使用一些 simulink 模型进行处理,然后结果将是发回c++进一步编程,通过udp实现数据传输,(c++为udp socket,simulink为udp real time send/receive block)。而且会重复几次。
我构建了一个 while 循环,其中 c++ 不断从 txt 文件中读取数据并通过 udp 将其发送到 simulink,效果很好,数据已乘以 2 并发送回 c++,但 c++ 不能接收从 simulink 发送的正确数据。它在每个周期接收到的数据都是“0”。但是如果我发送的数据是一个常量,那么 c++ 中的接收函数也可以正常工作。
ifstream file_x("x1.txt");
ifstream file_y("y1.txt");
ifstream file_z("z1.txt");
double x;
double y;
double z;
int main()
{
//Local Varaiable definition
cout<<"\t\t--------------------UDP Server----------------"<<endl;
cout<<endl;
WSADATA WinsockData;
int iWsaStartup;
int iWsaCleanup;
SOCKET UDPSocketServer1;
SOCKET UDPSocketClient3;
struct sockaddr_in UDPClient1;
struct sockaddr_in UDPServer3;
char Buffer1[200];
char Buffer3[200];
int iBufferLen1 = 200+1;
int iBufferLen3 = 200+1;
int iBind3;
int iReceiveFrom;
int iSendTo;
int iUDPClientLen1 = sizeof(UDPClient1);
int iUDPClientLen2 = sizeof(UDPClient2);
int iUDPServerLen3 = sizeof(UDPServer3);
int iCloseSocket1;
int iCloseSocket3;
//STEP-1: initialization of Winsock
iWsaStartup = WSAStartup(MAKEWORD(2,2), &WinsockData);
if (iWsaStartup != 0)
{
cout<<"WSAStartUp Fun Failed!"<<endl;
}
else
{
cout<<"WSAStartUp Success"<<endl;
}
//STEP-2: Fill the UDPClient(SOCKET ADDRESS) Structure
UDPClient1.sin_family = AF_INET;
UDPClient1.sin_addr.s_addr = inet_addr("127.0.0.1");
UDPClient1.sin_port = htons(8001);
UDPServer3.sin_family = AF_INET;
UDPServer3.sin_addr.s_addr = inet_addr("127.0.0.3");
UDPServer3.sin_port = htons(8003);
//STEP-3: Socket Creation
UDPSocketServer1 = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (UDPSocketServer1 == INVALID_SOCKET)
{
cout<<"Socket1 Creation Failed & Error No ->"<<WSAGetLastError()<<endl;
}
else
{
cout<<"Socket1 Creation Success"<<endl;
}
UDPSocketClient3 = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (UDPSocketClient3 == INVALID_SOCKET)
{
cout<<"Socket3 reation Failed = "<<WSAGetLastError()<<endl;
}
else
{
cout<<"Socket3 Creation Success"<<endl;
}
//STEP-4: Bind the server
iBind3 = bind(UDPSocketClient3, (SOCKADDR*)&UDPServer3, sizeof(UDPServer3));
if (iBind3 == SOCKET_ERROR)
{
cout<<"Binding Failed & Error No ->"<<WSAGetLastError()<<endl;
}
//STEP-4-1: SendTo Fun send data to client
while (!file_x.eof())
{
file_x >> x;
file_y >> y;
file_z >> z;
sprintf_s(Buffer1,200,"%0.2f\r\n %0.2f\r\n %0.2f\r\n",x,y,z);
iSendTo = sendto(UDPSocketServer1, Buffer1, iBufferLen1, MSG_DONTROUTE, (SOCKADDR*)&UDPClient1, sizeof(UDPClient1));
if (iSendTo == SOCKET_ERROR)
{
cout<<"Sending Data Failed & Error No ->"<<WSAGetLastError()<<endl;
}
else
{
cout<<"Sending Data Success"<<endl;
}
iReceiveFrom = recvfrom(UDPSocketClient3, Buffer3, iBufferLen3, MSG_PEEK, (SOCKADDR*)&UDPServer3, &iUDPServerLen3);
if (iReceiveFrom == SOCKET_ERROR)
{
cout<<"Receiving failed & Error No ->"<<WSAGetLastError()<<endl;
}
else
{
cout<<"Receiving Success"<<endl;
cout<<"Receive Data ->"<<Buffer3<<endl;
}
}
//STEP-6: CloseSocket Function
iCloseSocket1 = closesocket(UDPSocketServer1);
if (iCloseSocket1 == SOCKET_ERROR)
{
cout<<"Socket1 Closing failed & Error No ->"<<WSAGetLastError()<<endl;
}
else
{
cout<<"Socket1 Closing Success"<<endl;
}
iCloseSocket3 = closesocket(UDPSocketClient3);
if (iCloseSocket3 == SOCKET_ERROR)
{
cout<<"Socket3 Closing failed & Error No ->"<<WSAGetLastError()<<endl;
}
else
{
cout<<"Socket3 Closing Success"<<endl;
}
//STEP-7: WSACleanUp Fun for Terminating from DLL
iWsaCleanup = WSACleanup();
if (iWsaCleanup == SOCKET_ERROR)
{
cout<<"WSA Cleanup Success"<<endl;
}
else
{
cout<<"WSA Cleanup Success"<<endl;
}
system("pause");
return 0;
}
我发现 recvfrom 函数中的标志在这个问题上很重要,可以参考它的文档,我已经将 MSG_PEEK 更改为 0 并且考虑到我的应用程序,我使用了另一个项目来仅接收simulink传来数据,问题已解决
我正在尝试让我的 c++ 程序通过 udp 与 simulink 模型进行通信,特别是计划将数据从 c++ 传输到 simulink,并使用一些 simulink 模型进行处理,然后结果将是发回c++进一步编程,通过udp实现数据传输,(c++为udp socket,simulink为udp real time send/receive block)。而且会重复几次。
我构建了一个 while 循环,其中 c++ 不断从 txt 文件中读取数据并通过 udp 将其发送到 simulink,效果很好,数据已乘以 2 并发送回 c++,但 c++ 不能接收从 simulink 发送的正确数据。它在每个周期接收到的数据都是“0”。但是如果我发送的数据是一个常量,那么 c++ 中的接收函数也可以正常工作。
ifstream file_x("x1.txt");
ifstream file_y("y1.txt");
ifstream file_z("z1.txt");
double x;
double y;
double z;
int main()
{
//Local Varaiable definition
cout<<"\t\t--------------------UDP Server----------------"<<endl;
cout<<endl;
WSADATA WinsockData;
int iWsaStartup;
int iWsaCleanup;
SOCKET UDPSocketServer1;
SOCKET UDPSocketClient3;
struct sockaddr_in UDPClient1;
struct sockaddr_in UDPServer3;
char Buffer1[200];
char Buffer3[200];
int iBufferLen1 = 200+1;
int iBufferLen3 = 200+1;
int iBind3;
int iReceiveFrom;
int iSendTo;
int iUDPClientLen1 = sizeof(UDPClient1);
int iUDPClientLen2 = sizeof(UDPClient2);
int iUDPServerLen3 = sizeof(UDPServer3);
int iCloseSocket1;
int iCloseSocket3;
//STEP-1: initialization of Winsock
iWsaStartup = WSAStartup(MAKEWORD(2,2), &WinsockData);
if (iWsaStartup != 0)
{
cout<<"WSAStartUp Fun Failed!"<<endl;
}
else
{
cout<<"WSAStartUp Success"<<endl;
}
//STEP-2: Fill the UDPClient(SOCKET ADDRESS) Structure
UDPClient1.sin_family = AF_INET;
UDPClient1.sin_addr.s_addr = inet_addr("127.0.0.1");
UDPClient1.sin_port = htons(8001);
UDPServer3.sin_family = AF_INET;
UDPServer3.sin_addr.s_addr = inet_addr("127.0.0.3");
UDPServer3.sin_port = htons(8003);
//STEP-3: Socket Creation
UDPSocketServer1 = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (UDPSocketServer1 == INVALID_SOCKET)
{
cout<<"Socket1 Creation Failed & Error No ->"<<WSAGetLastError()<<endl;
}
else
{
cout<<"Socket1 Creation Success"<<endl;
}
UDPSocketClient3 = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (UDPSocketClient3 == INVALID_SOCKET)
{
cout<<"Socket3 reation Failed = "<<WSAGetLastError()<<endl;
}
else
{
cout<<"Socket3 Creation Success"<<endl;
}
//STEP-4: Bind the server
iBind3 = bind(UDPSocketClient3, (SOCKADDR*)&UDPServer3, sizeof(UDPServer3));
if (iBind3 == SOCKET_ERROR)
{
cout<<"Binding Failed & Error No ->"<<WSAGetLastError()<<endl;
}
//STEP-4-1: SendTo Fun send data to client
while (!file_x.eof())
{
file_x >> x;
file_y >> y;
file_z >> z;
sprintf_s(Buffer1,200,"%0.2f\r\n %0.2f\r\n %0.2f\r\n",x,y,z);
iSendTo = sendto(UDPSocketServer1, Buffer1, iBufferLen1, MSG_DONTROUTE, (SOCKADDR*)&UDPClient1, sizeof(UDPClient1));
if (iSendTo == SOCKET_ERROR)
{
cout<<"Sending Data Failed & Error No ->"<<WSAGetLastError()<<endl;
}
else
{
cout<<"Sending Data Success"<<endl;
}
iReceiveFrom = recvfrom(UDPSocketClient3, Buffer3, iBufferLen3, MSG_PEEK, (SOCKADDR*)&UDPServer3, &iUDPServerLen3);
if (iReceiveFrom == SOCKET_ERROR)
{
cout<<"Receiving failed & Error No ->"<<WSAGetLastError()<<endl;
}
else
{
cout<<"Receiving Success"<<endl;
cout<<"Receive Data ->"<<Buffer3<<endl;
}
}
//STEP-6: CloseSocket Function
iCloseSocket1 = closesocket(UDPSocketServer1);
if (iCloseSocket1 == SOCKET_ERROR)
{
cout<<"Socket1 Closing failed & Error No ->"<<WSAGetLastError()<<endl;
}
else
{
cout<<"Socket1 Closing Success"<<endl;
}
iCloseSocket3 = closesocket(UDPSocketClient3);
if (iCloseSocket3 == SOCKET_ERROR)
{
cout<<"Socket3 Closing failed & Error No ->"<<WSAGetLastError()<<endl;
}
else
{
cout<<"Socket3 Closing Success"<<endl;
}
//STEP-7: WSACleanUp Fun for Terminating from DLL
iWsaCleanup = WSACleanup();
if (iWsaCleanup == SOCKET_ERROR)
{
cout<<"WSA Cleanup Success"<<endl;
}
else
{
cout<<"WSA Cleanup Success"<<endl;
}
system("pause");
return 0;
}
我发现 recvfrom 函数中的标志在这个问题上很重要,可以参考它的文档,我已经将 MSG_PEEK 更改为 0 并且考虑到我的应用程序,我使用了另一个项目来仅接收simulink传来数据,问题已解决