查看原文
其他

写了一个文件传输软件

IT服务圈儿 2023-02-06

The following article is from 涛歌依旧 Author 点击关注👉👉

作者丨涛哥

来源丨涛歌依旧(ID:ai_taogeyijiu_2021)


最近遇到这样一件事情,有一个大文件,用微信从电脑A传输到电脑B,结果微信提示文件过大。这点小事情,略微有点郁闷。解决办法肯定是有的,比如下载一个文件传输软件,然后传送大文件。不过,我也懒得下载了,自己直接写一个传输软件吧。

接下来,我会基于tcp网络编程,实现文件传输的服务端和客户端,最终完成文件传输。为便于结果演示,我用环回地址测试。


ftp服务端实现

我们来看看服务端的思路,首先服务端要知道传输文件的大小,然后循环接收文件就行,实际程序如下,在关键地方都有详细注释:

#include <stdio.h>#include <winsock2.h>#pragma comment(lib, "ws2_32.lib") int main(){ // tcp连接部分 WORD wVersionRequested; WSADATA wsaData; wVersionRequested = MAKEWORD(1, 1); WSAStartup( wVersionRequested, &wsaData ); unsigned int sockSrv = socket(AF_INET, SOCK_STREAM, 0); SOCKADDR_IN addrSrv; addrSrv.sin_family = AF_INET; addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); addrSrv.sin_port = htons(8888); bind(sockSrv,(SOCKADDR*)&addrSrv, sizeof(SOCKADDR)); listen(sockSrv, 5); SOCKADDR_IN addrClient; int len = sizeof(SOCKADDR); unsigned int sockConn = accept(sockSrv,(SOCKADDR*)&addrClient, &len); // 接收ftp client发送过来的文件长度 char sizeFileStr[20] = {0}; recv(sockConn, sizeFileStr, sizeof(sizeFileStr) - 1, 0); int fileSize = atoi(sizeFileStr);   // 接收ftp client发送的文件并保存 char recvBuf[1024] = {0}; int recvTotalSize = 0; FILE *fp = fopen("server.rar", "wb"); while(recvTotalSize < fileSize) { int recvSize = recv(sockConn, recvBuf, sizeof(recvBuf), 0); recvTotalSize += recvSize; printf("received %f MB\n", recvTotalSize/(1024.0 * 1024.0)); fwrite(recvBuf, 1, recvSize, fp); } fclose(fp); if(recvTotalSize == fileSize) { printf("Done!"); } else { printf("Error!"); } closesocket(sockSrv); WSACleanup(); getchar(); return 0;}

编译并运行程序,开启服务端,等待客户端的连接,等待文件传输。


ftp客户端实现

客户端的思路也很直接,首先要计算出待传文件的大小,然后循环地读取文件并传输,具体代码如下:

#include <stdio.h>#include <winsock2.h>#pragma comment(lib, "ws2_32.lib") int main(){ // tcp连接部分 WORD wVersionRequested; WSADATA wsaData; wVersionRequested = MAKEWORD(1, 1); WSAStartup( wVersionRequested, &wsaData ); SOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0); SOCKADDR_IN addrSrv; addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); addrSrv.sin_family = AF_INET; addrSrv.sin_port = htons(8888); connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));   // ftp client读取文件长度 FILE *fp = fopen("MVC++6.0.rar", "rb");  fseek( fp, 0, SEEK_END );  int totalSize =  ftell(fp); fclose(fp);   // ftp client发送文件长度 char fileSizeStr[20] = {0}; itoa(totalSize, fileSizeStr, 10); send(sockClient, fileSizeStr, strlen(fileSizeStr) + 1, 0);   // ftp client发送文件 fp = fopen("MVC++6.0.rar", "rb"); int readSize = 0; int sendTotalSize = 0; char sendBuf[1024] = {0}; while((readSize = fread(sendBuf, 1, sizeof(sendBuf), fp)) > 0) { send(sockClient, sendBuf, readSize, 0); sendTotalSize += readSize; printf("sent %f MB\n", sendTotalSize/(1024.0 * 1024.0)); } fclose(fp); if(sendTotalSize == totalSize) { printf("Done!"); } else { printf("Error!"); } closesocket(sockClient); WSACleanup(); getchar(); return 0;}

编译客户端程序,把待传文件放在对应目录下,然后开启客户端,开始上传文件。


文件传输的结果

我们来看看文件的传输结果,左边是客户端,右边是服务端:

由此,完成了文件的传输。本文很简单,建议有兴趣的同学实际玩一下本文的例子,感受一下文件传输的过程,网络编程要多动手实践。希望大家有所收获。
本文是由实际问题引起的,进而想出解决方法。大家每天都会遇到问题,不要烦恼,要以解决问题为乐,兵来将挡,水来土掩,要相信问题一定有解决方法


1、你真的了解时间吗?

2、8 个令人惊叹的 Vue.js UI 组件,说不定用得上!

3、不记得Git命令?懒人版Git值得拥有!

4、Netty,从这里入手更易上手(含细节分析)

5、用70行Python编写一个概率编程语言

点分享

点点赞

点在看

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存