2009-07-20 66 views
1

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

+0

它获得了多少数据? – Javier 2009-07-20 21:35:48

+1

我发送800x600x3(1440000字节),我只收到65536字节 – DHamrick 2009-07-20 21:42:09

+0

你有一些代码吗?请记住,TCP是一个流,而不是面向消息的。 一次写入调用可能需要几次读取调用才能读取。或者几次写入调用可能只需要一次写入调用即可接收。记住要检查write()的返回值,你有责任编写所有的数据,write()调用可能只是发送部分数据。 – nos 2009-07-20 22:01:11

回答

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

很显然,我离开了实际的socket描述符,你需要为所有这些添加了很多错误检查。这并不意味着完整,更多的是展示这个想法。

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

1个单个IP分组的最大大小为65535,这是非常接近你打次数。我怀疑这是巧合。