客户端/服务器:如何在C中同步UDP发送和接收?

客户端/服务器:如何在C中同步UDP发送和接收?,c,udp,client,C,Udp,Client,我正在使用UDP编写一个简单的web服务器和客户端,到目前为止:程序可以相互连接,客户端可以发送请求,服务器可以读取请求,服务器可以识别客户端的IP地址和客户端的端口,服务器可以将消息发送回客户端 我的问题是,我的客户机代码在等待rcvfrom功能时被卡住,即使在服务器发送响应后也是如此。 下面是用于拾取服务器消息并返回套接字读取的字节数的函数: ssize_t receive_from_server(rdp_socket *rsocket, char *buffer, size_t buf_l

我正在使用UDP编写一个简单的web服务器和客户端,到目前为止:
  • 程序可以相互连接,
  • 客户端可以发送请求,
  • 服务器可以读取请求,
  • 服务器可以识别客户端的IP地址和客户端的端口,
  • 服务器可以将消息发送回客户端

我的问题是,我的客户机代码在等待
rcvfrom
功能时被卡住,即使在服务器发送响应后也是如此。

下面是用于拾取服务器消息并返回套接字读取的字节数的函数:

ssize_t receive_from_server(rdp_socket *rsocket, char *buffer, size_t buf_len){

  socklen_t sendsize = sizeof(rsocket->server_addr);
  bzero(&(rsocket->server_addr), sendsize);
  //STUCK HERE:
  return recvfrom(rsocket->sockfd, buffer, buf_len, 0,           
       (struct sockaddr*)&(rsocket->server_addr), &sendsize);
}
我将
SO\u SNDTIMEO
SO\u RCVTIMEO
的sockopts设置为几秒钟后超时

问题: 在短期内,我将为可靠的数据传输添加确认(ACKs)。我想丢失ACK可能是个问题,但我只是想知道,对于训练有素的人来说,这看起来是不是一个不同的问题

超时工作是否需要确认


如何同步我的客户端和服务器,使它们能够真正相互通信?

由于UDP不提供可靠性,您将需要重新传输丢失的数据。因为这看起来像是一个客户机请求服务器响应模型,所以最简单的重传实现可能是在等待响应超时时重新发送请求,然后再次等待响应。您可能希望实现一个重试计数器,并在一定次数的重试后放弃

如果
SO_RCVTIMEO
SO_SNDTIMEO
套接字选项似乎未生效,则可能是这些选项未针对该类型的套接字实施。检查
setsockopt()
调用的返回值以确保它们成功

作为一种解决方法,您可以将
receive\u from\u server()
函数更改为使用
poll()
select()
等待可读事件一段时间,而不是在
recvfrom()
中阻塞


我以前使用TCP解决过同样的问题,但现在我尝试使用UDP并实现我自己的措施来解决错误控制和数据包丢失。这段代码或您的描述中没有明显的错误。问题似乎出在服务器端。正如凯西指出的,没有明显的错误(据我所知)。您确定服务器发送的数据已返回到客户端吗?你试过wireshark或其他工具吗?
ssize_t receive_from_server(rdp_socket *rsocket, char *buffer, size_t buf_len){
  struct pollfd pfd = { rsocket->sockfd, POLLIN };
  int pollresult = poll(&pfd, 1, RECV_TIMEOUT_SECONDS * 1000);

  if (pollresult > 0) {
    socklen_t sendsize = sizeof(rsocket->server_addr);
    bzero(&(rsocket->server_addr), sendsize);

    return recvfrom(rsocket->sockfd, buffer, buf_len, MSG_DONTWAIT,           
      (struct sockaddr*)&(rsocket->server_addr), &sendsize);
  }

  if (pollresult == 0) {
      errno = ETIME;
  }

  return -1;
}