为什么我的网络TCP/UDP实现无法工作?

4

我想要一个服务器:

  • 可以发送和接收TCP消息。

  • 可以发送和接收UDP消息。

同时,有多个客户端:

  • 可以发送和接收TCP消息
  • 可以发送和接收UDP消息。

我在服务器端使用基本套接字和select功能,在客户端使用网络SFML模块(http://www.sfml-dev.org/tutorials/2.4/network-socket.php)。

在服务器端,我创建了我的套接字,并将TCP和UDP端口绑定到4005。

在客户端,我使用connect(host, ip)函数进行TCP连接,将UDP端口绑定到4006,因为我的UDP端口已经绑定到服务器端的4005上。

目前,我的TCP工作得很好,在两端(客户端和服务器)都可以发送和接收消息。

我正在尝试从服务器向客户端发送UDP数据包。为此,我从我想要发送消息的已接受客户端套接字中获取sockaddr_in信息(sockaddr_in由accept函数填充)。

但是当我发送它时,我的客户端没有收到它。

我按以下方式发送:

unsigned int UDPSocket::send(Message &buffer, sockaddr_in const &addr)
{
  sockaddr_in cpy;

  std::memcpy(&cpy, &addr, sizeof(sockaddr_in));
  //return ::send(_sock, buffer.getData().data(), buffer.getData().size(), 0);
  std::cout << "sending to " << buffer.getClientId() << std::endl;
  int fromsize = sizeof(sockaddr_in);
  cpy.sin_port = htons(4005 +1);
  std::cout << "sending to " << 4005 + 1 << std::endl;
  int ret = ::sendto(_sock, buffer.getMessage(), buffer.getSize(), 0, (struct sockaddr *) &cpy, fromsize);
  perror("sendto");
  std::cout << ret << std::endl;
  return ret;
}

如果ret大于0且perror返回成功,则应该发送消息。

我这样接收它:

bool              Network::updateQueueUDP()
{
  unsigned char   data[sizeof(Protocol::rtypePacket)];
  bool            ret = false;
  std::size_t     received;
  sf::IpAddress   sender;
  unsigned short  senderPort;

  if (_udpSocket.receive(data, sizeof(data), received, sender, senderPort) == sf::Socket::Done)
  {
    Message *msg = new Message();
    msg->setMessage(data, received, 0);
    _udpQueue.push(msg);
    std::cout << "pushing" << std::endl;
    ret = true;
  }
  return ret;
}

但是receive从不返回sf::Socket::Done

你有没有想过为什么我的客户端在UDP中没有收到任何内容?


我在哪里能找到“_udpSocket.receive”的代码或规范?我怀疑你可能不太理解它的功能,这也许不是接收UDP数据或检查“sf::Socket::Done”返回值的正确函数。 - Omnifarious
@Omnifarious 在这个页面上 http://www.sfml-dev.org/tutorials/2.4/network-socket.php - Dimitri Danilov
嗯,嗯...你得到了什么返回值? - Omnifarious
@Omnifarious 我得到了 sf::Socket::NotReady。 - Dimitri Danilov
1
哦!你把套接字设置成了非阻塞模式。你的程序会等到select说它可读之前才调用updateQueueUDP吗?另外一个可能的情况是你的缓冲区太小了,但那会导致Partial而不是NotReady - Omnifarious
1个回答

0

我错误地将错误的文件描述符传递给了sendto函数,因此它无法发送。


2
好的,根据你展示给我们的代码,我们永远也想不到那个问题。 :-/ - Omnifarious

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接