简体   繁体   English

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

[英]Transferring an Image using TCP Sockets in Linux

I am trying to transfer an image using TCP sockets using linux. 我试图使用Linux使用TCP套接字传输图像。 I have used the code many times to transfer small amounts but as soon as I tried to transfer the image it only transfered the first third. 我已经多次使用代码来传输少量数据,但是当我尝试传输图像时,它只转移了前三分之一。 Is it possible that there is a maximum buffer size for tcp sockets in linux? Linux中的tcp套接字是否有可能存在最大缓冲区大小? If so how can I increase it? 如果是这样我怎么能增加它? Is there a function that does this programatically? 是否有以编程方式执行此操作的函数?

I would guess that the problem is on the receiving side when you read from the socket. 我猜想当你从套接字读取时,问题出在接收端。 TCP is a stream based protocol with no idea of packets or message boundaries. TCP是基于流的协议,不知道数据包或消息边界。

This means when you do a read you may get less bytes than you request. 这意味着当您执行读取操作时,可能会获得比您请求的更少的字节数。 If your image is 128k for example you may only get 24k on your first read requiring you to read again to get the rest of the data. 例如,如果您的图像为128k,则在第一次读取时可能只会获得24k,需要您再次读取以获取其余数据。 The fact that it's an image is irrelevant. 它是一个图像的事实是无关紧要的。 Data is data. 数据就是数据。

For example: 例如:

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

TCP sends the data in pieces, so you're not guaranteed to get it all at once with a single read (although it's guaranteed to stay in the order you send it). TCP会将数据分段发送,因此您无法保证只需一次读取即可获得所有数据(尽管它保证按照您发送的顺序保留)。 You basically have to read multiple times until you get all the data. 在获得所有数据之前,您基本上必须多次阅读。 It also doesn't know how much data you sent on the receiver side. 它也不知道你在接收器端发送了多少数据。 Normally, you send a fixed size "length" field first (always 8 bytes, for example) so you know how much data there is. 通常,您首先发送固定大小的“长度”字段(例如,总是8个字节),以便您知道有多少数据。 Then you keep reading and building a buffer until you get that many bytes. 然后你继续阅读并构建一个缓冲区,直到你得到那么多字节。

So the sender would look something like this (pseudocode) 所以发件人看起来像这样(伪代码)

int imageLength;
char *imageData;

// set imageLength and imageData

send(&imageLength, sizeof(int));
send(imageData, imageLength);

And the receiver would look like this (pseudocode) 接收器看起来像这样(伪代码)

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

Obviously I left off the actual socket descriptor and you need to add a lot of error checking to all of that. 显然我没有实际的套接字描述符,你需要为所有这些添加大量的错误检查。 It wasn't meant to be complete, more to show the idea. 它并不意味着完整,更多的是为了展示这个想法。

The maximum size for 1 single IP packet is 65535, which is extremely close to the number you are hitting. 1个单个IP数据包的最大大小为65535,非常接近您所命中的数字。 I doubt that is a coincidence. 我怀疑这是巧合。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM