客户端服务器回声程序进入UDP的僵局

Client-Server echo program going into deadlock in UDP

本文关键字:UDP 僵局 服务器 回声 程序 客户端      更新时间:2023-10-16

以下是UDP客户端服务器回波程序的客户端代码:

ret_val = sendmmsg(socket_id, msgs, no_of_packets, 0);
//I send message to the server
if(ret_val == -1)
  std::cerr << "Message sending failed.n";
else{
  cout << ret_val << " messages sentn";
  /************************************************************************/
  char buffers[no_of_packets][packet_size + 1];
  msgs = new struct mmsghdr[no_of_packets];
  iovecs = new struct iovec[no_of_packets];
  memset(msgs, 0, sizeof(msgs));
  memset(iovecs, 0, sizeof(iovecs));
  for(int i = 0;i < no_of_packets;i++){
    iovecs[i].iov_base = buffers[i];
    iovecs[i].iov_len = packet_size;
    msgs[i].msg_hdr.msg_iov = &iovecs[i];
    msgs[i].msg_hdr.msg_iovlen = 1;
  }
  //and receive the packet here, but the program hangs here
  ret_val = recvmmsg(socket_id, msgs, no_of_packets, 0, NULL);

我的程序悬挂在这里,知道为什么会发生吗?以下是首先收到然后成功发送的服务器端代码,但是在服务器首次发送后,我的客户端无法在悬挂时读取它。

ret_val = recvmmsg(socket_id, msgs, no_of_packets, 0, NULL);
if(ret_val < 0){
  break;
}
else{
  cout << ret_val << " messages receivedn";
  for(int i = 0;i < ret_val;i++){
    buffers[i][msgs[i].msg_len] = 0;
    printf("Trip %d : %sn", trip, buffers[i]);
  }
  /************************************************************************/
  if(connect(socket_id, (struct sockaddr *) &server_addr, sizeof(server_addr)) == -1){
    perror("connect()");
    exit(EXIT_FAILURE);
  }
  ret_val = sendmmsg(socket_id, msgs, no_of_packets, 0);
  //This send is successful, but since my client hangs,
  //the server hangs as well since the 'recvmmsg' at the top gets nothing from the client
  if(ret_val == -1)
    std::cerr << "Message sending failed.n";
  else
    cout << ret_val << " messages sentn";

服务器代码中的这一行看起来可疑:

if(connect(socket_id, (struct sockaddr *) &server_addr, sizeof(server_addr)) == -1)

什么是server_addr?当然,这不是任何数据包的源地址,从先前的呼叫返回到recvmmsg

只需删除connect调用即可。

我可以写更多,但是您是否有任何特殊原因您使用recvmmsgsendmmsg而不是recvfromsendto

以下是使用UDP套接字实现Echo服务器的一种简单的方法:

const int MAX_UDP_MESSAGE_SIZE = 65535
unsigned char message[MAX_UDP_MESSAGE_SIZE+1];
int rcvReslt, sndResult;
sockaddr_in addr = {};
socklen_t addrLength = sizeof(addr);
rcvResult = recvfrom(socket_id, message, MAX_UDP_MESSAGE_SIZE, 0, (sockaddr*)&addr, &addrLength);
if (rcvResult > 0)
{
    message[rcvResult] = 0; // null terminate the message
    printf("Trip %d : %sn", trip, message);
    // echo back
    sndResult = sendto(socket_id, message, rcvResult, 0, (sockaddr*)&addr, addrLength);
}
else
{
    int error_code = errno;
    printf("Error: %dn", error_code);
}

显然您已连接到错误的目标。您根本不需要连接。recvfrommsg()都返回源IP:端口。只需寄回同一个地方即可。