14.9 Socket 高效文件传输
网络上的文件传输功能也是很有必要实现一下的,网络传输文件的过程通常分为客户端和服务器端两部分。客户端可以选择上传或下载文件,将文件分块并逐块发送到服务器,或者从服务器分块地接收文件。服务器端接收来自客户端的请求,根据请求类型执行对应的操作,并根据发送的文件名或其他标识来确定要传输的文件。在实现文件传输之前,需要先打开要传输的文件,并获取文件的大小信息,也可以通过其他方式获取文件的信息。在客户端和服务器端都准备就绪后,可以通过套接字来发送文件数据。在传输文件的过程中,可以将文件分解为若干个数据包进行传输,以减少数据传输中的丢包或传输错误。每个数据包的长度可以根据实际情况进行选择,通常选择1024字节或更大,也可以设置成更小的值。传输文件的过程中,还需要实现一定的错误处理机制,例如检测传输过程中的超时、丢包、不完整数据等情况,并在必要时进行错误重传或协商其他解决方案。
首先无论时服务端还是客户端都需要封装两个函数,其中GetFileName()函数用于当用户传入文件的具体路径信息时自动获取到该文件的文件名,第二个函数GetFileSize()则用于传入文件路径并自动获取到该文件的字节数。
// 传入路径得到文件名
char* GetFileName(char* Path)
{
if (strchr(Path, '\\'))
{
char ch = '\\';
char* ref = strrchr(Path, ch) + 1;
return ref;
}
else
{
char ch = '/';
char* ref = strrchr(Path, ch) + 1;
return ref;
}
}
// 获取文件大小
int GetFileSize(std::string FileName)
{
FILE* pointer = NULL;
pointer = fopen(FileName.c_str(), "rb");
if (pointer != NULL)
{
fseek(pointer, 0, SEEK_END);
int size = ftell(pointer);
fclose(pointer);
return size;
}
return 0;
}接着我们来看一下RecvFile()接收文件函数是如何实现的,首先第一个发送用于向服务端发出我需要下载具体的那个目录下的文件,接着服务端会返回该目录文件的长度,此时我们通过fopen()创建一个新文件,并以此循环接收该文件的长度,每次接收成功后自动的fwrite写出到文件中,当文件被接收完毕后,则通过fclose(pointer)保存并关闭文件。
// 接收文件bool RecvFile(SOCKET ptr, char* LocalPath, char* RemoteFile){// 发送需要下载的文件路径send(ptr, RemoteFile, strlen(RemoteFile), 0);// 接收文件长度long long file_size = 0;recv(ptr, (char*)&file_size, sizeof(int), 0);if (file_size
页:
[1]