厦门市城市建设档案馆网站,牡丹江最新信息网0453,网站怎么优化搜索,菏泽做网站推广网络上的文件传输功能也是很有必要实现一下的#xff0c;网络传输文件的过程通常分为客户端和服务器端两部分。客户端可以选择上传或下载文件#xff0c;将文件分块并逐块发送到服务器#xff0c;或者从服务器分块地接收文件。服务器端接收来自客户端的请求#xff0c;根据…网络上的文件传输功能也是很有必要实现一下的网络传输文件的过程通常分为客户端和服务器端两部分。客户端可以选择上传或下载文件将文件分块并逐块发送到服务器或者从服务器分块地接收文件。服务器端接收来自客户端的请求根据请求类型执行对应的操作并根据发送的文件名或其他标识来确定要传输的文件。
在实现文件传输之前需要先打开要传输的文件并获取文件的大小信息也可以通过其他方式获取文件的信息。在客户端和服务器端都准备就绪后可以通过套接字来发送文件数据。在传输文件的过程中可以将文件分解为若干个数据包进行传输以减少数据传输中的丢包或传输错误。每个数据包的长度可以根据实际情况进行选择通常选择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 0){return false;}// 保存文件到指定目录下char *file_name GetFileName(RemoteFile);char file_all_name[1024] { 0 };strcat(file_all_name, LocalPath);strcat(file_all_name, file_name);std::cout 生成保存路径: file_all_name std::endl;FILE* pointer fopen(file_all_name, wb);char buffer[1024] { 0 };if (pointer ! NULL){long long length 0;long long total_length 0;// 循环接收字节数据,每次接收1024字节while ((length recv(ptr, buffer, 1024, 0)) 0){// 写出文件并判断是否写出成功if (fwrite(buffer, sizeof(char), length, pointer) length){break;}// 每次累加递增total_length length;memset(buffer, 0, 1024);// 判断文件长度是否全部接收完毕if (total_length file_size){std::cout 文件接收完毕, 接收字节数: total_length std::endl;fclose(pointer);return true;}}fclose(pointer);}return false;
}对于SendFile()发送文件而言首先我们接收到客户端传来的文件路径并通过该路径得到该文件的具体长度第一次调用发送函数将文件的长度传递给客户端此时打开我们所需要发送的文件并通过循环的方式向客户端传输当数据包传输完毕后则自动关闭文件。
// 发送指定文件
bool SendFile(SOCKET ptr)
{// 接收文件路径char file_path[1024] { 0 };recv(ptr, file_path, 1024, 0);// 得到文件长度并发送给服务端long long file_size GetFileSize(file_path);if (file_size 0){return false;}send(ptr, (char*)file_size, sizeof(int), 0);std::cout 发送文件长度: file_size std::endl;// 循环发送数据char buffer[1024] { 0 };FILE* pointer fopen(file_path, rb);if (pointer ! NULL){long long length 0;long long total_length 0;// 循环发送数据while ((length fread(buffer, sizeof(char), 1024, pointer)) 0){send(ptr, buffer, length, 0);memset(buffer, 0, 1024);total_length length;}if (total_length file_size){return true;}}return false;
}14.9.1 服务端实现
如下代码展示了如何使用Winsock进行TCP协议的文件传输。首先使用WSAStartup函数对Winsock库进行初始化。然后创建一个socket设置IP地址、端口号等信息并将该socket和本地服务端的地址绑定起来。接下来对该socket进行监听等待客户端的连接请求。
当有客户端连接请求到来时accept函数会接收请求并创建一个新的socket与客户端进行通信。在与客户端通信的过程中可以通过send和recv函数进行数据的传输实现文件的上传和下载功能。此处的代码调用RecvFile函数该函数为自定义实现的接收文件函数负责接收数据并将接收到的文件存储到指定的路径下。
int main(int argc, char* argv[])
{WSADATA wsaData;if (WSAStartup(MAKEWORD(2, 2), wsaData) ! 0)exit(1);// 声明并初始化一个服务端(本地)的地址结构 sockaddr_in server_addr;server_addr.sin_family AF_INET;server_addr.sin_addr.S_un.S_addr INADDR_ANY;server_addr.sin_port htons(8087);// 创建socket SOCKET m_Socket socket(AF_INET, SOCK_STREAM, 0);if (SOCKET_ERROR m_Socket)exit(1);// 绑定socket和服务端(本地)地址 if (SOCKET_ERROR bind(m_Socket, (LPSOCKADDR)server_addr, sizeof(server_addr)))exit(1);// 监听 if (SOCKET_ERROR listen(m_Socket, 10))exit(1);sockaddr_in client_addr;int client_addr_len sizeof(client_addr);SOCKET m_New_Socket accept(m_Socket, (sockaddr*)client_addr, client_addr_len);// 接收远程d://lyshark.exe放到本地的d://11g/目录下bool ref RecvFile(m_New_Socket, (char*)d://11g/, (char*)d://lyshark.exe);std::cout 接收状态: ref std::endl;closesocket(m_New_Socket);closesocket(m_Socket);WSACleanup();system(pause);return 0;
}14.9.2 客户端实现
如下客户端代码实现了一个基于TCP协议的文件传输客户端。首先使用WSAStartup函数对Winsock库进行初始化。然后创建一个socket并设置服务端的IP地址和端口号。之后通过connect函数与服务端建立连接连接成功后调用SendFile函数进行文件传输将指定的文件发送到服务端。文件传输完成后关闭socket连接清除Winsock资源。
int main(int argc, char* argv[])
{while (true){WSADATA wsaData;if (WSAStartup(MAKEWORD(2, 2), wsaData) ! 0)exit(1);// 创建socket SOCKET c_Socket socket(AF_INET, SOCK_STREAM, 0);//指定服务端的地址 sockaddr_in server_addr;server_addr.sin_family AF_INET;server_addr.sin_addr.S_un.S_addr inet_addr(127.0.0.1);server_addr.sin_port htons(8087);if (SOCKET_ERROR ! connect(c_Socket, (LPSOCKADDR)server_addr, sizeof(server_addr))){bool ref SendFile(c_Socket);std::cout 文件发送状态: ref std::endl;}closesocket(c_Socket);WSACleanup();Sleep(1000);}return 0;
}文件传输功能代码就这些其实理解起来并不难读者可自行编译并运行上述代码运行后则可接收远程d://lyshark.exe文件并放到本地的d://11g/目录下输出效果图如下 本文作者 王瑞 本文链接 https://www.lyshark.com/post/323aa250.html 版权声明 本博客所有文章除特别声明外均采用 BY-NC-SA 许可协议。转载请注明出处