1. 程式人生 > 其它 >淺談C++實現的TCP實時檔案傳輸

淺談C++實現的TCP實時檔案傳輸

環境:win11,VS2019

分為服務端和客戶端,實現檔案的傳輸

廢話不多說,直接上程式碼,儘量在程式碼裡多加點註釋叭

//服務端
/*寫在前面:
眾所周知,TCP在進行傳輸的時候需要三次握手,很幸運,這些東西windows都封裝好了,不用我一個初學者再寫(我也不會2333)
於是,需要注意的就只有網路通訊本身了。
怎樣才能定位到對方的計算機和對方的對應通訊程式呢?
IP地址用來定位計算機,每一個程式所對應的有一個1~32768的一個數字稱為埠,用這個數字來定位計算機內部眾多的程式。
下文的註釋把套接字比喻為電話機,可能比較明瞭。
*/
#include<cstdio> #include<winsock2.h> #include
<cstring> #include<Windows.h> #pragma comment(lib,"ws2_32.lib")//連結lib庫, using namespace std; int main() { //初始化套接字(winsocket) WSADATA wsaData; WSAStartup(MAKEWORD(2, 2), &wsaData);//MAKEWORD,把兩個32位int繫結為一個數,(版本號) //安裝電話機(建立套接字)PF_INET=Ipv4 SOCKET hServSock = socket(PF_INET, SOCK_STREAM, 0
);//IPv4協議,流式套接字,0表示TCP //繫結電話號碼和分機號(ip&埠) SOCKADDR_IN servAddr;//定義一個套接字(結構體) memset(&servAddr, 0, sizeof(servAddr));//清空結構體servAddr內的東西 servAddr.sin_family = AF_INET;//服務端,所以需要的是地址簇(family),AF_INET表示IPv4協議 servAddr.sin_addr.s_addr = htonl(INADDR_ANY);//使用自身的IP地址。htonl:將主機的無符號長整形數轉換成網路位元組順序;INADDR_ANY表示本機IP
servAddr.sin_port = htons(7777);//0~1024不能用;確定埠號;htons轉化型別 bind(hServSock, (SOCKADDR*)&servAddr, sizeof(servAddr));//把電話機和電話號碼繫結,即套接字和儲存地址和埠號的結構體繫結。 //監聽,拿起電話聽筒聽對面是否說話 listen(hServSock, 5);//最多5臺電話 //發現監聽物件,接電話 //獲得對方的ip,埠號 SOCKADDR_IN clntAddr; int clntAdrSz = sizeof(clntAddr); SOCKET hClntSock = accept(hServSock, (SOCKADDR*)&clntAddr, &clntAdrSz);//建立 //說話 //看一下對方的ip地址 //printf("%s", inet_ntoa(clntAddr.sin_addr)); char buf[1025]={0}; recv(hClntSock,buf,1024,0);//先接受檔名 //printf("%s\n", buf); FILE* fp = fopen(buf, "wb");//用檔名創造二進位制檔案 int bytes; while ((bytes = recv(hClntSock, buf, 1024, 0)) > 0)//每次接受1024個位元組存在buf裡 { fwrite(buf, 1, bytes,fp);//把buf裡的東西存在檔案中 } fclose(fp);//完成,關閉檔案 closesocket(hClntSock);//銷燬套接字 closesocket(hServSock); //空檔案,接收內容 WSACleanup();//回收套接字 return 0; }

 

 

/*寫在前面
有了前面的服務端,會發現,其實客戶端和服務端長得是很像的
話不多說,直接開始
*/

#include<cstdio> #include<winsock2.h> #include<cstring> #pragma comment(lib,"ws2_32.lib")
using namespace std; int main() { //初始化套接字(winsocket) WSADATA wsaData; WSAStartup(MAKEWORD(2, 2), &wsaData); //打電話 SOCKET hClntSOCK = socket(PF_INET,SOCK_STREAM ,0);//建立流式套接字TCP //127.0.0.1(本機)7777(埠號) SOCKADDR_IN clntAddr; memset(&clntAddr,0,sizeof(clntAddr));//同服務端,清空結構體 clntAddr.sin_family=AF_INET; clntAddr.sin_addr.s_addr=inet_addr("127.0.0.1"); clntAddr.sin_port=htons(7777); //連線 connect(hClntSOCK,(SOCKADDR*)&clntAddr,sizeof(clntAddr)); //傳送一個檔名 send(hClntSOCK,"1.mp4",1024,0); FILE* fp = fopen("1.mp4", "rb");//開啟檔案,只讀 char buf[1024] = { 0 }; int bytes; while ((bytes = fread(buf, 1, 1024, fp) )> 0)//讀取檔案內容,每次一個1024位元組 { send(hClntSOCK, buf, 1024, 0);//把buf裡存的東西send給服務端 } fclose(fp);//傳輸完成,關閉檔案 closesocket(hClntSOCK); WSACleanup();//回收套接字 return 0; }

 

(To be continued)