我有一个设备可以侦听端口IN_PORT上的UDP数据包,并在端口OUT_PORT上回显消息。我可以使用Packet Sender等测试软件与它进行通信。
我必须编写一个C ++库(目前是Win32)来与设备通信。我做了几次测试,但我还是无法沟通。我的猜测是使用这个工作流程:
如果我使用Packet Sender实用程序在本地工作(设备地址= 127.0.0.1)来模拟设备,则此方法有效。我无法使用相同的工作流连接到远程地址,即使在同一子网中(例如我的PC地址:192.168.1.2,远程PC地址192.168.1.5),因为我收到WSAEADDRNOTAVAIL错误。
我已经测试了几个不同的工作流程,并在这里和那里阅读了关于这个主题的几个讨论,但没有一个工作,非常好。
有人可以给我一些关于这个问题的提示。
谢谢!
MIX
答案 0 :(得分:1)
您的工作流程略有错误。它应该更像是这样:
答案 1 :(得分:0)
我在 Remy Lebeau 提示后更改了我的代码。它现在有效。如果有人想看看并发现一些弱点,或提出改进建议,我会很高兴(一个“正常工作”的代码永远不够;它也必须“闪耀”!)。注释标记代码的上一个(错误)版本。
#pragma comment (lib, "Ws2_32.lib")
#include <winsock2.h>
#include <stdlib.h>
#include <stdio.h>
#include <STRING>
#define IN_PORT 18
#define OUT_PORT 17
#define LOCAL_IP "10.0.10.108"
#define DEVICE_IP "10.0.10.104"
#define DEFAULT_BUFLEN 1024
int main(int argc, char *argv[])
{
WSADATA wsaData;
SOCKET sck;
struct sockaddr_in sckAddrInfo;
bool terminate;
char dataBuffer[DEFAULT_BUFLEN];
int rcvDataLength;
int sckAddrInfoLength;
WSAStartup(MAKEWORD(2,2), &wsaData);
sck = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
memset((&sckAddrInfo), 0, sizeof(sckAddrInfo));
sckAddrInfo.sin_family = AF_INET;
sckAddrInfo.sin_port = htons(IN_PORT);
//sckAddrInfo.sin_addr.s_addr = inet_addr(DEVICE_IP); // WRONG! Must bind local address
sckAddrInfo.sin_addr.s_addr = inet_addr(LOCAL_IP);
bind(sck, (struct sockaddr*)(&sckAddrInfo), sizeof(sckAddrInfo));
terminate = false;
sckAddrInfoLength = sizeof(sckAddrInfo);
while(!terminate)
{
printf("Write echo request: ");
gets(dataBuffer);
sckAddrInfo.sin_addr.s_addr = inet_addr(DEVICE_IP); // Must set device address, too, not just output port
sckAddrInfo.sin_port = htons(OUT_PORT);
sendto(sck, dataBuffer, strlen(dataBuffer), 0, (struct sockaddr*)(&sckAddrInfo), sizeof(sckAddrInfo));
memset(dataBuffer, '\0', DEFAULT_BUFLEN);
rcvDataLength = recvfrom(sck, dataBuffer, DEFAULT_BUFLEN, 0, (struct sockaddr*)(&sckAddrInfo), &sckAddrInfoLength);
printf("Device answer: %s\n", dataBuffer);
if(strcmp(dataBuffer, "quit") == 0)
terminate = true;
}
closesocket(sck);
WSACleanup();
return 0;
}