首页 文章

使用两台主机之间的不同端口进行UDP套接字通信

提问于
浏览
0

我有一个设备在端口IN_PORT上侦听UDP数据包并在端口OUT_PORT上回显消息 . 我可以使用Packet Sender等测试软件与之通信 .

我必须编写一个C库(目前是Win32)来与设备通信 . 我做了几次测试,但我还是无法沟通 . 我的猜测是使用这个工作流程:

  • 创建套接字

  • 使用设备地址,AF_INET系列和侦听端口(OUT_PORT)填充sockaddr_in结构

  • 绑定套接字

  • 用IN_PORT更改sockaddr_in.sin_port并发送数据包(使用sendto)

  • 等待答案(使用recvfrom)

  • 从4开始重复

如果我使用Packet Sender实用程序在本地工作(设备地址= 127.0.0.1)来模拟设备,则此方法有效 . 我无法使用相同的工作流连接到远程地址,即使在同一子网中(例如我的PC地址:192.168.1.2,远程PC地址192.168.1.5),因为我收到WSAEADDRNOTAVAIL错误 .

我已经测试了几个不同的工作流程,并在这里和那里阅读了关于这个主题的几个讨论,但没有一个工作,非常好 .

有人可以给我一些关于这个问题的提示 .

谢谢!

混合

2 回答

  • 1

    你的工作流程有点不对劲 . 它应该更像是这样:

    • 创建套接字

    • 使用 the address of the local network adapter that is communicating with the device ,AF_INET系列和listenig端口(OUT_PORT)填充sockaddr_in结构

    • 绑定套接字

    • 更改 sockaddr.sin_addr with device address ,并使用IN_PORT更改sockaddr_in.sin_port,并发送数据包(使用sendto)

    • 等待答案(使用recvfrom)

    • 从4开始重复

  • 0

    我按照 Remy Lebeau 提示改变了我的代码 . 它现在有效 . 如果有人想看看并发现一些弱点,或建议改进,我会很高兴(一个代码"just works"永远不够;它也必须"shine"!) . 注释标记代码的上一个(错误)版本 .

    #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;
    }
    

相关问题