socket read在返回之前获取所有数据

时间:2014-05-20 02:57:03

标签: c sockets message-queue

我正在编写一个tcp代理,它维护一个消息队列。一旦从服务器获得响应,我需要从队列中弹出前面的消息。问题是我的服务器响应消息的大小很大,读取函数将在收集所有数据之前返回。我应该如何处理这个问题?

3 个答案:

答案 0 :(得分:2)

在没有看到任何代码片段来了解所涉及的数据结构的情况下,听起来您只需要遍历套接字read()调用,直到您已经读取足够的数据来满足“完整消息”的约束。收到完整的消息后,您可以将其放在队列中并弹出第一个消息,或者如果它是第一个消息则返回该消息。

答案 1 :(得分:1)

粗略地说,你需要一个这样的循环:

size_t read_buffer(int sockfd, char *buffer, size_t reqlen)
{
    char   *cur_buffer = buffer;
    size_t  bytes_left = reqlen;
    ssize_t bytes_read;
    while ((bytes_read = read(sockfd, cur_buffer, bytes_left)) > 0)
    {
        cur_buffer += bytes_read;
        bytes_left -= bytes_read;
    }
    return(cur_buffer - buffer);
}

您可以决定如何处理读取错误 - 是否返回读取的字节数或错误指示(可能是-1)。代码返回读取的字节数;如果它不是请求的长度,那么假设丢失的字节永远不会出现是合理的(所以可能你最终会忽略调用代码中读取的内容)。您可能想要识别bytes_read == -1 && errno == EINTR(读取被中断)并尝试再次阅读。

警告:未编译,更少测试,代码!

答案 2 :(得分:1)

我不知道为什么你认为你需要排队信息,收集完整的回复等等,而你还没有回答发布的评论,但是一旦初始握手完成,正常的代理服务器所要做的就是在它们到达时同时复制两个方向的字节,而不必同时关注消息:

while ((count = recv(insocket, buffer, 0, sizeof buffer, 0)) > 0)
{
    send(outsocket, buffer, 0, count, 0);
}

每个连接需要两个线程,每个线程在每个方向上执行此操作。当两个线程都退出这些循环时,关闭两个套接字。