我正在尝试使用linux使用TCP套接字传输图像。我已经多次使用代码来传输少量数据,但是当我尝试传输图像时,它只转移了前三分之一。 Linux中的tcp套接字是否有可能存在最大缓冲区大小?如果是这样我怎么能增加它?是否有以编程方式执行此操作的函数?
答案 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,非常接近您要击中的数字。我怀疑这是巧合。