1. 程式人生 > >76)客戶端往服務器發文件

76)客戶端往服務器發文件

方案 head 指針 inet_addr buffer pro clas bsp OS

基礎:

    其實就是在TCP的那個解決方案裏面,加一個SendFile的工程,在工程裏面建一個SendFile.cpp的文件,裏面放CLient的代碼

    同時進行修改代碼,SendFile代碼:

  1 #include<iostream>
  2 #include<Winsock2.h>
  3 
  4 #include<fstream>
  5 
  6 using namespace std;
  7 
  8 #pragma comment(lib, "ws2_32.lib")
  9 
 10 struct FileHeader
 11
{ 12 char fileName[MAX_PATH]; 13 int fileSize; 14 }; 15 int main() 16 { 17 18 //第一步 19 WORD wVersionRequested; 20 WSADATA wsaData; 21 int err; 22 23 24 wVersionRequested = MAKEWORD(2, 2); 25 26 err = WSAStartup(wVersionRequested, &wsaData); 27 if
(err != 0) { 28 printf("WSAStartup failed with error: %d\n", err); 29 return 1; 30 } 31 32 33 34 if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) { 35 36 printf("Could not find a usable version of Winsock.dll\n
"); 37 WSACleanup(); 38 return 1; 39 } 40 else 41 printf("The Winsock 2.2 dll was found okay\n"); 42 43 //第二步: 44 45 SOCKET sock=socket(AF_INET ,SOCK_STREAM,IPPROTO_TCP ); 46 if(sock==INVALID_SOCKET) 47 { 48 WSACleanup(); 49 return 1; 50 } 51 52 //第三步 53 cout<"請輸入服務器IP:"<<endl; 54 char szip[100]={0}; 55 cin>>szip; 56 57 sockaddr_in clientService; 58 InetPton(AF_INET,szip,(void*)&addr.sin_addr.S_un.S_addr);//這是幹啥的,我都不知道 59 60 clientService.sin_family = AF_INET; 61 //clientService.sin_addr.s_addr = inet_addr("192.168.3.153"); 62 clientService.sin_port = htons(1234); 63 64 connect(sock,(SOCKADDR *) & clientService, sizeof (clientService)); 65 66 67 //第七步 68 char filePath[MAX_PATH]={0}; 69 char *pfilePath=filePath; 70 //發東西了 71 //文件頭-->包含文件名和文件大小(兩種數據類型,所以發一個結構體就行了,所以在上面定義一個結構體FileHeader) 72 FileHeader fh; 73 cout<<"請輸入要傳輸的文件:"<<endl; 74 cin>>filePath; 75 //我們要從帶有文件名的路徑裏面獲得文件名; 76 while(*pfilePath++!=\0); 77 //現在pfilePath就指到最後一個字母那塊了,現在開始往回走 78 while(*(--pfilePath)=\\);//只要讀到\,就停下來 79 pfilePath++ 80 strcpy_s(fh.fileName,MAX_PATH,pfilePath);//獲得文件名 81 //接下來獲得文件大小,因為文件只有打開才能獲得文件大小,所以 我們接下來就是打開文件,但是C裏面沒有獲得文件大小的函數,C++裏有,MFC裏有 82 83 //C++這個裏面有獲取文件大小的函數#include<fstream> 84 fstream fs; 85 fs.open(filePath,fstream::in|fstream::binary);//以二進制流的形式讀,無論是什麽文件,這樣都能讀出來 86 //在C++沒有直接獲得文件大小的函數,但是他有獲得文件指針所指的文件大小的函數,所以下面我要移動文件指針,文件指針最開始指向文件頭,我要把文件指針移到文件尾,然後才是獲得的整個文件的大小 87 88 fs.seekg(0,fs::end);//移動文件指針到尾部,不偏移 89 90 fh.fileSize=fs.telg();//獲得文件指針位置的文件大小 91 fs.seekg(0,fs::beg);//移動文件指針到頭部,不偏移(就是再移回去) 92 93 94 95 96 //發送 97 send(sock,(const char*)&fh,sizeof(fh),0); 98 99 100 //等待對方回復--> 101 char sResult[4]={0};//存來自服務器的答復內容 102 char content_buffer[1024]={0}; 103 recv(sock,sResult,sizeof(sResult),0); 104 105 if(0==strcmp(sResult,""))//如果肯定回復--》 106 { 107 108 while(1) 109 { 110 //讀文件, 111 fs.read(content_buffer,sizeof(content_buffer)); 112 //發文件 113 //應該是讀多少就發多少,而不應該是固定發多少,因為有可能,我讀到的文件內容小於你設定的讀的文件的大小 114 int RealResultNum=fs.gcount();//獲得當前真正讀的文件大小 115 if(RealResultNum==0) 116 { 117 break; 118 } 119 send(sock,content_buffer,RealResultNum); 120 } 121 122 123 } 124 125 //關閉文件 126 fs.close(); 127 128 //第八步 129 130 closesocket(sock); 131 WSACleanup(); 132 return 1; 133 134 135 136 137 138 139 system("pause"); 140 return 0; 141 }

修改服務器代碼:

  

76)客戶端往服務器發文件