我正在尝试实现简单的文件传输。以下是我一直在测试的两种方法:
方法一:发送和接收而不拆分文件。 我对文件大小进行了硬编码以便于测试。
发件人:
send(sock,buffer,107,NULL); //sends a file with 107 size
接收器:
char * buffer = new char[107];
recv(sock_CONNECTION,buffer,107,0);
std::ofstream outfile (collector,std::ofstream::binary);
outfile.write (buffer,107);
输出符合预期,文件未损坏,因为我发送的.txt
文件包含与原始文件相同的内容。
方法二:通过拆分接收方的内容来发送和接收。每个循环5个字节。
发件人:
send(sock,buffer,107,NULL);
接收器:
char * buffer = new char[107]; //total file buffer
char * ptr = new char[5]; //buffer
int var = 5;
int sizecpy = size; //orig size
while(size > var ){ //collect bytes
recv(sock_CONNECTION,ptr,5,0);
strcat(buffer,ptr); //concatenate
size= size-var; //decrease
std::cout<<"Transferring.."<<std::endl;
}
std::cout<<"did it reach here?"<<std::endl;
char*last = new char[size];
recv(sock_CONNECTION,last,2,0); //last two bytes
strcat(buffer,last);
std::ofstream outfile (collector,std::ofstream::binary);
outfile.write (buffer,107);
输出:文本文件包含无效字符,尤其是在开头和结尾。
问题:如何使方法2工作?尺寸相同但产生不同的结果。原始文件和方法2上的新文件的相似度约为98%~99%,而方法1的相似度为100%。传输文件的最佳方法是什么?
答案 0 :(得分:3)
传输文件的最佳方法是什么?
通常我没有回答像最好的方法这样的问题。但在这种情况下,显而易见:
注意:您不需要在客户端将内存中的所有块组合在一起,只需将它们附加到存储介质中的文件即可。校验和(CRC)通常可以通过数据块运行来计算。
答案 1 :(得分:1)
我看到的初始问题是std::strcat。您不能在未初始化的缓冲区上使用它。此外,您不是复制空终止的c字符串。您正在复制大小的缓冲区。最好使用std::strncat:
char * buffer = new char[107]; //total file buffer
char * ptr = new char[5]; //buffer
int var = 5;
int sizecpy = size; //orig size
// initialize buffer
*buffer = '\0'; // add null terminator
while(size > var ){ //collect bytes
recv(sock_CONNECTION,ptr,5,0);
strncat(buffer, ptr, 5); // strncat only 5 chars
size= size-var; //decrease
std::cout<<"Transferring.."<<std::endl;
}
除此之外,您应该将错误检查,以便套接字库可以告诉您通信是否出错。
答案 2 :(得分:1)
不同意Galik。最好不要使用strcat,strncat或除预期输出缓冲区之外的任何东西。
TCP非常有趣。你真的不知道你将获得多少数据,但你会得到它或错误。
这将一次读取最多MAX个字节。 somethingRegex | xargs -I {} sh -c 'printf "found \033[34m{}\033[39m";dummy {}'
MAX到你想要的任何东西。
#define
更有趣的是,写入输出缓冲区,这样您就不必存储整个文件。在这种情况下,MAX应该是一个更大的数字。
std::unique_ptr<char[]> buffer (new char[size]);
int loc = 0; // where in buffer to write the next batch of data
int bytesread; //how much data was read? recv will return -1 on error
while(size > MAX)
{ //collect bytes
bytesread = recv(sock_CONNECTION,&buffer[loc],MAX,0);
if (bytesread < 0)
{
//handle error.
}
loc += bytesread;
size= size-bytesread; //decrease
std::cout<<"Transferring.."<<std::endl;
}
bytesread = recv(sock_CONNECTION,&buffer[loc],size,0);
if (bytesread < 0)
{
//handle error
}
std::ofstream outfile (collector,std::ofstream::binary);
outfile.write (buffer.get(),size);