2017-02-26 83 views
0

我在一個週期內發送多個UDP數據報,並使用sendmmsgrecvmmsg系統調用接收它們。我的客戶端代碼是這樣的:即使客戶端停止發送消息,服務器仍在運行

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--); 
} 

客戶端不斷髮送消息,直到間隔爲正。而我的服務器端代碼保持接收這些消息:

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]); 
    } 
    } 
} 

問題是我的服務器從客戶端發送完所有消息即使在while循環不會退出。如何讓服務器知道消息接收已完成?

+0

使用一條消息作爲最終消息,如果服務器收到該消息,它可以中斷循環。 –

回答

0

問題是我的服務器沒有退出while循環,即使在 客戶端完成發送所有消息。

UDP服務器沒有任何客戶端連接的概念,UDP服務器也不知道客戶端何時「已完成發送」。

你的recvmmsg調用只是等到客戶端發送數據報。如果有客戶端可以告訴服務器退出的場景,則需要在應用程序協議級別完成。

相關問題