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

在Linux中使用TCP套接字传输映像

  •  1
  • DHamrick  · 技术社区  · 16 年前

    我正在尝试使用linux使用TCP套接字传输映像。我曾多次使用该代码传输少量数据,但一旦我尝试传输图像,它只传输了前三分之一。linux中tcp套接字是否有最大缓冲区大小?如果是这样,我该如何增加它?是否有一个函数可以通过编程来实现这一点?

    3 回复  |  直到 16 年前
        1
  •  1
  •   CodeGoat    16 年前

    这意味着当你进行读取时,你可能会得到比你请求的字节少的字节。例如,如果你的图像是128k,你第一次读取时可能只会得到24k,需要你再次读取才能获得其余的数据。这是一个图像的事实无关紧要。数据就是数据。

    例如:

    int read_image(int sock, int size, unsigned char *buf) {
       int bytes_read = 0, len = 0;
       while (bytes_read < size && ((len = recv(sock, buf + bytes_read,size-bytes_read, 0)) > 0)) {
           bytes_read += len;
       }
       if (len == 0 || len < 0) doerror();
       return bytes_read;
    }
    
        2
  •  3
  •   nos    16 年前

    TCP将数据分块发送,因此不能保证一次读取就能一次性获取所有数据(尽管可以保证数据会按照发送顺序进行)。你基本上必须多次阅读,直到你得到所有的数据。它也不知道你在接收端发送了多少数据。通常,你首先发送一个固定大小的“长度”字段(例如,总是8个字节),这样你就知道有多少数据。然后,你继续读取和构建缓冲区,直到得到那么多字节。

    所以发送者看起来像这样(伪代码)

    int imageLength;
    char *imageData;
    
    // set imageLength and imageData
    
    send(&imageLength, sizeof(int));
    send(imageData, imageLength);
    

    int imageLength;
    char *imageData;
    
    guaranteed_read(&imageLength, sizeof(int));
    imageData = new char[imageLength];
    guaranteed_read(imageData, imageLength);
    
    void guaranteed_read(char* destBuf, int length)
    {
        int totalRead=0, numRead;
        while(totalRead < length)
        {
            int remaining = length - totalRead;
            numRead = read(&destBuf[totalRead], remaining);
            if(numRead > 0)
            {
                totalRead += numRead;
            }
            else
            {
                // error reading from socket
            }
        }
    }
    

        3
  •  0
  •   mox1    16 年前

    1个单一IP数据包的最大大小为65535,与您要达到的数字非常接近。我怀疑这是巧合。