清理窗口套接字内部缓冲区

时间:2013-04-12 20:37:25

标签: c++ sockets winsock msdn

我想知道是否有办法清理窗口套接字内部缓冲区,因为我想要实现的是这个

while(1){
 for(i=0;i<10;i++){
    sendto(...) //send 10 UDP datagrams
 }
 for(i=0;i<10;i++){
    recvfrom (Socket, RecBuf, MAX_PKT_SIZE, 0,
                   (SOCKADDR*) NULL, NULL);
    int Status = ProcessBuffer(RecBuf);
    if (Status == SomeCondition)
        MagicalSocketCleanUP(Socket); //clean up the rest of stuff in the socket, so that it doesn't effect the reading for next iteration of the outer while loop
        break; //occasionally the the receive loop needs to terminate before finishing off all 10 iteration
 }
} 

所以我要求是否有一个功能来清理套接字中剩余的内容,以便它不会影响我的下一次阅读?谢谢

1 个答案:

答案 0 :(得分:1)

从内部接收套接字缓冲区清除数据的方法是读取数据,直到没有更多数据要读取。如果以非阻塞方式执行此操作,则无需等待select()中的更多数据,因为EWOUDBLOCK错误值表示内部接收套接字缓冲区为空。

int MagicalSocketCleanUP(SOCKET Socket) {
    int r;
    std::vector<char> buf(128*1024);
    do {
        r = recv(Socket, &buf[0], buf.size(), MSG_DONTWAIT);
        if (r < 0 && errno == EINTR) continue;
    } while (r > 0);
    if (r < 0 && errno != EWOULDBLOCK) {
        perror(__func__);
        //... code to handle unexpected error
    }
    return r;
}

但这并不完全安全。套接字的另一端也可能已经将好的数据发送到套接字缓冲区,因此这个例程可能丢弃的内容超过你想要丢弃的内容。

相反,套接字上的数据应以这样的方式构成,以便您知道感兴趣的数据何时到达。因此,除了清理API之外,您可以扩展ProcessBuffer()以放弃输入,直到找到感兴趣的数据。

更简单的机制是套接字双方之间的消息交换。输入错误状态后,发件人会发送“DISCARDING UNTIL <TOKEN>”消息。接收方发回“<TOKEN>”并知道只处理“<TOKEN>”消息之后的数据。 “<TOKEN>”可以是随机序列。