Client-Server echo程序在UDP中进入死锁状态

时间:2017-02-26 09:21:37

标签: c++ sockets udp

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

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 sent\n";
  /************************************************************************/
  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 received\n";
  for(int i = 0;i < ret_val;i++){
    buffers[i][msgs[i].msg_len] = 0;
    printf("Trip %d : %s\n", 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 sent\n";

2 个答案:

答案 0 :(得分:0)

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

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 : %s\n", trip, message);

    // echo back
    sndResult = sendto(socket_id, message, rcvResult, 0, (sockaddr*)&addr, addrLength);
}
else
{
    int error_code = errno;
    printf("Error: %d\n", error_code);
}

答案 1 :(得分:0)

显然,您已连接到错误的目标。你根本不需要连接。 recvfrommsg()都返回源IP:端口。只需发回相同的地方。