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

时间:2009-07-20 21:23:43

标签: linux tcp

我正在尝试使用linux使用TCP套接字传输图像。我已经多次使用代码来传输少量数据,但是当我尝试传输图像时,它只转移了前三分之一。 Linux中的tcp套接字是否有可能存在最大缓冲区大小?如果是这样我怎么能增加它?是否有以编程方式执行此操作的函数?

3 个答案:

答案 0 :(得分:3)

我猜想从套接字读取时问题出在接收端。 TCP是一种基于流的协议,不知道数据包或消息边界。

这意味着当您执行读取操作时,您可能获得的字节数少于您请求的字节数。例如,如果您的图像为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;
}

答案 1 :(得分:1)

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
        }
    }
}

显然,我没有使用实际的套接字描述符,你需要为所有这些添加大量的错误检查。它并不意味着完整,更多的是表明这个想法。

答案 2 :(得分:0)

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