代码之家  ›  专栏  ›  技术社区  ›  ggkmath

我必须在某处遇到缓冲区限制,使用recv()从TCP套接字接收数据。

  •  0
  • ggkmath  · 技术社区  · 14 年前

    我正在从通过TCP套接字连接的测试仪器下载6KB的数据。我正在使用sock_流:

    if((MySocket=socket(PF_INET,SOCK_STREAM,0))==-1) exit(1);
    

    我没有设置任何缓冲区大小,所以我假设使用的是默认值。我接收数据有问题。声明如下:

      if((recv(MySocket, &YRaw[indx], sizeChunk*2, 0))==-1)
         {perror("recv()"); exit(9); }  // where sizeChunk=3000; sizeof(YRaw[0])=2
    

    其中,yraw是一个3000对象数组,每个对象是2个字节。

    在运行代码之后,我观察到的问题是,在通过yraw数组的过程中,有大约3/4的路径,有一个由零组成的字符串,这就是我初始化数组的目的。看起来,接收函数的工作正常,最多为数组的3/4,然后跳过一块Yraw数组(保留初始化值),然后再次拾取,Yraw数组将填充。缓冲区中还有要读取的数据,等于Yraw数组中跳过的值的数目。

    我怀疑这与系统中的某个缓冲区有关。有人能解释一下怎么解决这个问题吗?

    我不知道它是否相关,但我还设置了tcp_nodelay,如下所示:

    // TCP_NODELAY option minimizes latency by instructing system to send small msgs immediately
    // Insert setsockopt() before connect() occurs
    int StateNODELAY = 1; // turn NODELAY on
    if(setsockopt(MySocket, IPPROTO_TCP,TCP_NODELAY,
       (void *) &StateNODELAY, sizeof StateNODELAY)==-1) {perror("setsockopt()"); exit(2); };
    

    顺祝商祺!

    2 回复  |  直到 14 年前
        1
  •  3
  •   sth Wojciech Parzych    14 年前

    recv() 不一定要填满整个缓冲区。它只读取可用的内容,并返回已读取的字节数。

    所以检查返回值,看看有多少数据可用,处理这些数据,然后调用 记录() 直到你收到你所期望的所有数据。

        2
  •  0
  •   Andre Holzner    14 年前

    您应该明确地存储 recv (即,不仅要检查它是不是-1)。这是实际读取的字节大小,您需要知道缓冲区中有多少字节是有效的。

    除此之外,您应该检查是否可以在不阻塞的情况下读取更多的字节,并在阻塞之前读取更多的字节。

    缓冲区大小限制可以在系统中的任何位置,例如以太网MTU,甚至在发送设备上。