无法通过UDP发送数据

时间:2018-08-03 06:20:57

标签: c++ visual-c++

我无法使用代码中的IP地址将UDP数据发送到系统。

我们通过构造函数建立连接,然后在下面的代码中发送消息。

这是我的头文件。

class UDPConnect
 {
  private:
   bool connected;
   SOCKET s;
   struct sockaddr_in server, si_other;
   int slen, recv_len;

   public:
        UDPConnect(const int iPort );   
        UDPConnect(const int iPort , const char* strHostName);
        int ReadIncomingPacket(byte *buffer, unsigned int buf_size);    
        int SendPacket(byte* buffer, unsigned int buf_size , const char* 
        strHostName);
        ~UDPConnect();
    };

这是函数定义。

 UDPConnect::UDPConnect(const int iPORT , const char* strHostName)
  {
    this->connected = false;
    this->s;
    WSADATA wsa;

    //Initialise winsock
   std::cout << ("\nInitialising Winsock...") << std::endl;
   if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
    {
     std::cout << ("Failed. Error Code : %d", WSAGetLastError()) << 
     std::endl;
    exit(EXIT_FAILURE);
    }

  //Create a socket
  if ((this->s = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET)
  {
     std::cout << ("Could not create socket : %d", WSAGetLastError());
  }

 std::cout << ("Socket created.\n");

//Prepare the sockaddr_in structure
this->server.sin_family = AF_INET;
this->server.sin_addr.s_addr = inet_addr( strHostName );
this->server.sin_port = htons(iPORT);


//Bind
//if (::bind(this->s, (struct sockaddr *)&this->server, sizeof(this->server)) 
 == SOCKET_ERROR)
if (::bind(this->s, (struct sockaddr *)&this->server, 0) == SOCKET_ERROR)
{
    printf("Bind failed with error code : %d", WSAGetLastError());
    //exit(EXIT_FAILURE);
}
puts("Bind done");

this->connected = true;

}

///////////////////////////////////////////////// /////////////////////////

int UDPConnect::SendPacket(byte *buffer, unsigned int buf_size , const char* 
 strHostName)
 {

   this->server.sin_addr.s_addr = inet_addr( strHostName );
  if ((this->recv_len = sendto(this->s, (char*)buffer, buf_size + 1, 0, 
  (struct sockaddr *) &this->si_other, slen)) == SOCKET_ERROR)
   {
     std::cout << ("No Outgoing packet : %d", WSAGetLastError());
     //return -1;
   }

return recv_len;

}

1 个答案:

答案 0 :(得分:3)

我发现您的代码中有很多错误。

  • 当参数strHostName实际上不能接受主机名(仅IP地址)时,会引起误解。您应该重命名它们,否则要实现主机名解析。

  • printf样式的说明符与std::cout混合。

  • 使用无效的bind()值调用namelen。第一次您是正确的,但是您将其注释掉了。

  • 发送数据包时,
  • 递增buf_size。 UDP对原始字节进行操作,并且原始数据不是以null结尾的,只有C样式的字符串是。如果调用方要发送以null结尾的字符串,则应在传递的buf_size值中包含null终止符。

  • 使用错误的sendto()和不确定的sockaddr_in值调用slen。另外,不提供任何方法来指定要发送到的目标端口。

尝试更多类似的方法:

class UDPConnect
{
private:
    SOCKET s;
public:
    UDPConnect(ushort local_port, const char *local_addr = NULL);
    ~UDPConnect();
    int ReadIncomingPacket(byte *buffer, unsigned int buf_size);
    int SendPacket(byte* buffer, unsigned int buf_size, const char* remote_addr, ushort remote_port);
};

UDPConnect::UDPConnect(ushort local_port, const char* local_addr)
    : s(INVALID_SOCKET)
{
    WSADATA wsa;
    int err;

    //Initialise winsock
    std::cout << "\nInitialising Winsock..." << std::endl;
    err = WSAStartup(MAKEWORD(2, 2), &wsa);
    if (err != 0)
    {
        std::cout << "Failed. Error Code : " << err << std::endl;
        exit(EXIT_FAILURE);
    }

    //Create a socket
    if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET)
    {
        err = WSAGetLastError();
        std::cout << "Could not create socket : " << err << std::endl;
        exit(EXIT_FAILURE);
    }

    std::cout << "Socket created." << std::endl;

    //Prepare the sockaddr_in structure
    struct sockaddr_in server = {};
    server.sin_family = AF_INET;
    server.sin_port = htons(local_port);
    if (local_addr)
    {
        server.sin_addr.s_addr = inet_addr(local_addr);
        if (server.sin_addr.s_addr == INADDR_NONE)
        {
            std::cout << "Invalid local address specified" << std::endl;
            closesocket(s);
            exit(EXIT_FAILURE);
        }
    }
    else
        server.sin_addr.s_addr = INADDR_ANY;

    //Bind
    if (::bind(s, (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR)
    {
        err = WSAGetLastError();
        std::cout << "Bind failed with error code : " << err << std::endl;
        closesocket(s);
        exit(EXIT_FAILURE);
    }
    std::cout << "Bind done";
}

UDPConnect::~UDPConnect()
{
    closesocket(s);
}

int UDPConnect::ReadIncomingPacket(byte *buffer, unsigned int buf_size)
{
    int recv_len;
    if ((recv_len = recvfrom(s, (char*)buffer, buf_size, 0, NULL, NULL)) == SOCKET_ERROR)
    {
        int err = WSAGetLastError();
        std::cout << "No Incoming packet : " << err;
        //return -1;
    }
    return recv_len;
}

int UDPConnect::SendPacket(byte *buffer, unsigned int buf_size, const char* remote_addr, ushort remote_port)
{
    struct sockaddr_in si_other = {};
    int send_len;

    //Prepare the sockaddr_in structure
    si_other.sin_family = AF_INET;
    si_other.sin_addr.s_addr = inet_addr(remote_addr);
    si_other.sin_port = htons(remote_port);

    if ((send_len = sendto(s, (char*)buffer, buf_size, 0, (struct sockaddr *) &si_other, sizeof(si_other))) == SOCKET_ERROR)
    {
        int err = WSAGetLastError();
        std::cout << "No Outgoing packet : " << err;
        //return -1;
    }
    return send_len;
}