寫了一個文件傳輸軟件

大家好,我是濤哥。

最近遇到這樣一件事情,有一個大文件,用微信從電腦 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;
}

編譯客戶端程序,把待傳文件放在對應目錄下,然後開啓客戶端,開始上傳文件。


文件傳輸的結果

我們來看看文件的傳輸結果,左邊是客戶端,右邊是服務端:

由此,完成了文件的傳輸。本文很簡單,建議有興趣的同學實際玩一下本文的例子,感受一下文件傳輸的過程,網絡編程要多動手實踐。希望大家有所收穫。

本文是由實際問題引起的,進而想出解決方法。大家每天都會遇到問題,不要煩惱,要以解決問題爲樂,兵來將擋,水來土掩,要相信問題一定有解決方法。

最近假期天天打乒乓球,肚子贅肉已經減了一圈,輕鬆多了,精神也好很多,只要有空,就要運動起來。剛纔球友又在喊我了,要走起了。咱們明天見哈。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/dXPFQ6UP2_p3131I_YM6GQ