[英]Sending files in socket programming tcp
I am trying to implement a simple file transfer. 我正在尝试实现一个简单的文件传输。 Below here is two methods that i have been testing:
下面是我正在测试的两种方法:
Method one: sending and receiving without splitting the file. 方法一:发送和接收而不拆分文件。 I hard coded the file size for easier testing.
我对文件大小进行了硬编码,以便于测试。
sender: 发件人:
send(sock,buffer,107,NULL); //sends a file with 107 size
receiver: 接收器:
char * buffer = new char[107];
recv(sock_CONNECTION,buffer,107,0);
std::ofstream outfile (collector,std::ofstream::binary);
outfile.write (buffer,107);
The output is as expected, the file isn't corrupted because the .txt
file that i sent contains the same content as the original. 输出符合预期,该文件未损坏,因为我发送的
.txt
文件包含与原始内容相同的内容。
Method two: sending and receiving by splitting the contents on receiver's side. 方法二:通过在接收方拆分内容进行发送和接收。 5 bytes each loop.
每个循环5个字节。
sender: 发件人:
send(sock,buffer,107,NULL);
Receiver: 接收器:
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);
Output: The text file contains invalid characters especially at the beginning and the end. 输出:文本文件包含无效字符,尤其是在开头和结尾。
Questions: How can i make method 2 work? 问题:如何使方法2起作用? The sizes are the same but they yield different results.
大小相同,但结果不同。 the similarity of the original file and the new file on method 2 is about 98~99% while it's 100% on method one.
方法2的原始文件和新文件的相似度约为98〜99%,而方法1的相似度为100%。 What's the best method for transferring files?
传输文件的最佳方法是什么?
What's the best method for transferring files?
传输文件的最佳方法是什么?
Usually I'm not answering questions like What's the best method . 通常,我不会回答“ 什么是最好的方法”之类的问题。 But in this case it's obvious:
但是在这种情况下,很明显:
Note: You don't need to combine all chunks in memory at the client side, but just append them to a file at a storage medium. 注意:您不需要在客户端将内存中的所有块组合在一起,而只需将它们附加到存储介质上的文件中即可。 Also the checksum (CRC) usually can be calculated from running through data chunks.
通常,校验和(CRC)通常可以通过遍历数据块来计算。
The initial problems I see are with std::strcat . 我看到的最初问题是与std :: strcat有关 。 You can't use it on an uninitialized buffer.
您不能在未初始化的缓冲区上使用它。 Also you are not copying a null terminated c-string.
另外,您不复制空终止的c字符串。 You are copying a sized buffer.
您正在复制大小缓冲区。 Better to use std::strncat for that:
最好使用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;
}
beyond that you should really as error checking so the sockets library can tell you if anything went wrong with the communication. 除此之外,您还应该真正进行错误检查,以便套接字库可以告诉您通信是否出现问题。
Disagree with Galik. 与Galik不同意。 Better not to use strcat, strncat, or anything but the intended output buffer.
最好不要使用strcat,strncat或除预期的输出缓冲区以外的任何东西。
TCP is knda fun. TCP很有趣。 You never really know how much data you are going to get, but you will get it or an error.
您永远不会真正知道将要获取多少数据,但是您会得到它或出错。
This will read up to MAX bytes at a time. 一次最多读取MAX个字节。
#define
MAX to whatever you want. #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);
Even more fun, write into the output buffer so you don't have to store the whole file. 更加有趣的是,写入输出缓冲区,这样您就不必存储整个文件。 In this case MAX should be a bigger number.
在这种情况下,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.