[英]Sending files in socket programming tcp
我正在尝试实现一个简单的文件传输。 下面是我正在测试的两种方法:
方法一:发送和接收而不拆分文件。 我对文件大小进行了硬编码,以便于测试。
发件人:
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%。 传输文件的最佳方法是什么?
传输文件的最佳方法是什么?
通常,我不会回答“ 什么是最好的方法”之类的问题。 但是在这种情况下,很明显:
注意:您不需要在客户端将内存中的所有块组合在一起,而只需将它们附加到存储介质上的文件中即可。 通常,校验和(CRC)通常可以通过遍历数据块来计算。
我看到的最初问题是与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;
}
除此之外,您还应该真正进行错误检查,以便套接字库可以告诉您通信是否出现问题。
与Galik不同意。 最好不要使用strcat,strncat或除预期的输出缓冲区以外的任何东西。
TCP很有趣。 您永远不会真正知道将要获取多少数据,但是您会得到它或出错。
一次最多读取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);
更加有趣的是,写入输出缓冲区,这样您就不必存储整个文件。 在这种情况下,MAX应该更大。
std::ofstream outfile (collector,std::ofstream::binary);
char buffer[MAX];
int bytesread; //how much data was read? recv will return -1 on error
while(size)
{ //collect bytes
bytesread = recv(sock_CONNECTION,buffer,MAX>size?size:MAX,0);
// MAX>size?size:MAX is like a compact if-else: if (MAX>size){size}else{MAX}
if (bytesread < 0)
{
//handle error.
}
outfile.write (buffer,bytesread);
size -= bytesread; //decrease
std::cout<<"Transferring.."<<std::endl;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.