代码之家  ›  专栏  ›  技术社区  ›  Gordon Wrigley

有没有办法冲洗POSIX插槽?

  •  33
  • Gordon Wrigley  · 技术社区  · 16 年前

    8 回复  |  直到 16 年前
        1
  •  31
  •   Fantastory    13 年前

    设置TCP_节点延迟,然后将其重置回来怎么样? 也许这可以在发送重要数据之前完成,或者在我们完成发送消息时完成。

    send(sock, "notimportant", ...);
    send(sock, "notimportant", ...);
    send(sock, "notimportant", ...);
    int flag = 1; 
    setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(int));
    send(sock, "important data or end of the current message", ...);
    flag = 0; 
    setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(int));
    

    正如linux手册页所说

    TCP_节点延迟。。。设置此选项将强制显式刷新挂起的输出。。。

        2
  •  21
  •   user207421    7 年前

    fflush() ,但我想你可能指的是网络插座。实际上没有冲洗这些东西的概念。最接近的是:

    1. shutdown(sock, SHUT_WR)

    2. 在TCP套接字上,使用sockopt禁用Nagle算法 TCP_NODELAY ,这通常是一个糟糕的想法,它不会可靠地实现你想要的,即使它在最初的调查中似乎处理好了。

    很有可能在用户协议级别处理任何需要“刷新”的问题都是正确的。

        3
  •  13
  •   hagello    4 年前

    在RFC1122中,您要查找的对象的名称是“推送”。 然而,似乎没有实现“推送”的相关TCP API实现。唉,没有运气。

    一些答案和评论涉及Nagle算法。他们中的大多数人似乎都认为Nagle算法会延迟每一个时间 每一个 邮寄 这种假设是不正确的。唠叨延迟发送 ( http://www.unixguide.net/network/socketfaq/2.11.shtml ).

    换言之:TCP将发送 第一 数据包(一行数据包) . 只有当连接速度慢且您的计算机没有及时收到确认时,Nagle才会延迟发送 后续数据

    • 达到或超过超时时间
    • 最后一个未确认的数据包已确认,或
    • 您禁用了Nagle或
    • 您关闭了连接的发送方向

    后续数据 尽可能地。这意味着:如果应用程序调用 send() 若要多次传输单个复合请求,请尝试重写应用程序。在用户空间中组装复合请求,然后调用 . 一旦这也节省了上下文切换(比大多数用户空间操作要昂贵得多)。

    总而言之,Nagle并不是蛮力的减少数据包碎片的方法,一些人可能认为是这样。相反:在我看来,它似乎是一种有用的、动态的和有效的方法,可以保持良好的响应时间以及用户数据和头数据之间的良好比率。也就是说,你应该知道如何有效地处理它。

        4
  •  11
  •   Mysticial rexford    12 年前

    据我所知,在标准TCP/IP套接字接口中,没有任何方法可以“一直到远程端”刷新数据并确保数据已被确认。

    setsockopt() 属于 TCP_NODELAY

        5
  •  1
  •   user3458 user3458    16 年前

    看起来您需要在应用程序级别执行此操作。。。

        6
  •  0
  •   Norman Ramsey    16 年前

    TCP只提供尽力而为的传输,因此让所有字节离开机器A的行为与它们在机器B接收到的所有字节是异步的。当然,TCP/IP协议栈知道,但我不知道如何询问TCP栈以确定发送的所有内容是否都已确认。

    在应用程序级别 . 打开第二个TCP套接字作为后台通道,让远程合作伙伴向您发送一个确认,确认它已收到您想要的信息。这将花费双倍,但将是完全可移植的,并将节省您几个小时的编程时间。

        7
  •  0
  •   user1402866    13 年前

        8
  •  0
  •   Zaffy    4 年前

    有一个 linux-specific way 要在TCP套接字上执行此操作,请执行以下操作:

    您不会强制tcp堆栈“立即发送数据”,但请记住,您和内核正在以尽可能快的速度发送数据。您可以稍微减少 send 和实际交付 TCP_NODELAY .

    但基本上,通过这样做 邮寄 你已经完成了你的部分,你只需要等待tcp完成它的部分。

    ioctl 在插座上 SIOCOUTQ TIOCOUTQ 查询交付状态,然后等待完成。这应该足够了。特别是对于发送应用程序级数据包片段这样的用例。

        9
  •  -3
  •   Stuart Deal    10 年前

    使用fsync():

    fsync(sock_fd);