Server still running despite client stopped sendin

2019-09-13 02:33发布

问题:

I'm sending multiple UDP datagrams in a cycle and receiving them using sendmmsg and recvmmsg system calls. My client-side code is this :

struct mmsghdr *msgs;
struct iovec *iovecs;
while(interval){
  msgs = new struct mmsghdr[no_of_packets];
  iovecs = new struct iovec[no_of_packets];
  for(int i = 0;i < no_of_packets;i++){
    memset(&iovecs[i], 0, sizeof(iovecs[i]));
    iovecs[i].iov_base = (void *) to_string(i + 1).c_str();
    iovecs[i].iov_len = 1;
  }
  memset(msgs, 0, sizeof(msgs));
  for(int i = 0;i < no_of_packets;i++){
    msgs[i].msg_hdr.msg_iov = &iovecs[i];
    msgs[i].msg_hdr.msg_iovlen = 1;
  }
  ret_val = sendmmsg(socket_id, msgs, no_of_packets, 0);
  no_of_packets++;
  if(ret_val == -1)
    std::cerr << "Message sending failed.\n";
  else
    cout << ret_val << " messages sent\n";
  sleep(interval--);
}

The client keeps sending messages until interval is positive. And my server side code keeps receiving these messages :

while(true){
  msgs = new struct mmsghdr[no_of_packets];
  iovecs = new struct iovec[no_of_packets];
  char buffers[no_of_packets][packet_size + 1];
  memset(msgs, 0, sizeof(msgs));
  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;
  }
  ret_val = recvmmsg(socket_id, msgs, no_of_packets, 0, NULL);
  no_of_packets++;
  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", i + 1, buffers[i]);
    }
  }
}

The problem is my server doesn't exit from the while loop even after the client finishes sending all the messages. How can I make the server aware that the message receving has finished ?

回答1:

The problem is my server doesn't exit from the while loop even after the client finishes sending all the messages.

UDP servers do not have any concept of a client connection, nor does a UDP server know when a client has "finished sending".

Your recvmmsg call is just going to wait until a client sends it a datagram. If there's a scenario where your client can tell the server to exit, it needs to be done at the application protocol level.



标签: c++ sockets udp