程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 一個簡單的在本地傳輸文件的網絡程序

一個簡單的在本地傳輸文件的網絡程序

編輯:C++入門知識

經常在CSDN貼吧看見很多關於網絡之間傳輸的例子(比如傳輸截屏文件),所以很想寫一個作為學習。

此程序設定很簡單,就是在本地傳輸。當然,要擴展到網絡也很簡單,改個ip就ok了。

基本思路:

雙方遵循一個包頭格式,根據包頭確定之後的操作。

服務器代碼:

[cpp] 
#include <string> 
#include <io.h> 
 
#define PORT 6666 
 
struct PacketHeader 

    char code[10];      // 指令:"EOF"=斷開連接  "PIC"=接收圖片 
    char name[50];      // 名字:包括後綴 
    LONG32 size;        // 大小:字節 
    PacketHeader() 
    { 
        memset(code,0,sizeof(code)); 
        memset(name,0,sizeof(name)); 
        size = 0; 
    } 
}; 
 
// 在本地傳輸圖片 
void server() 

    WSADATA wd; 
    int ret = WSAStartup(MAKEWORD(2,2),&wd); 
    if(ret != 0) 
    { 
        cout<<"Initialize Winsock Failed! "<<GetLastError()<<endl;; 
        return; 
    } 
    cout<<"WSAStartup OK"<<endl; 
 
    sockaddr_in addr_serv,addr_cli; 
    int sock_listen,sock_accept; 
    try{ 
        sock_listen = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); 
        if(sock_listen == SOCKET_ERROR) 
        { 
            cout<<"create socket failed! "<<GetLastError()<<endl; 
            throw 1; 
        } 
        cout<<"socket OK"<<endl; 
 
        memset((void*)&addr_serv,0,sizeof(sockaddr)); 
        addr_serv.sin_family = AF_INET; 
        addr_serv.sin_addr.S_un.S_addr = INADDR_ANY; 
        addr_serv.sin_port = htons(PORT); 
 
        ret = bind(sock_listen,(sockaddr*)&addr_serv,sizeof(addr_serv)); 
        if(ret != 0) 
        { 
            cout<<"bind failed! "<<GetLastError()<<endl; 
            throw 2; 
        } 
        cout<<"bind OK"<<endl; 
 
        ret = listen(sock_listen,1); 
        if(ret != 0) 
        { 
            cout<<"listen failed! "<<GetLastError()<<endl; 
            throw 2; 
        } 
        cout<<"listen OK"<<endl; 
 
        int addrlen = sizeof(addr_cli); 
        sock_accept = accept(sock_listen,(sockaddr*)&addr_cli,&addrlen); 
        if(sock_accept == INVALID_SOCKET) 
        { 
            cout<<"accept failed! "<<GetLastError()<<endl; 
            throw 2; 
        } 
        cout<<"accept OK"<<endl; 
        closesocket(sock_listen);   //停止監聽 
 
        while(true) 
        { 
            cout<<"輸入:(EOF表示斷開連接,文件名表示發送文件,例如sumos.txt)"<<endl; 
            string input; 
            cin>>input; 
            if(input.compare("EOF") == 0) 
            { 
                PacketHeader ph; 
                strcpy_s(ph.code,"EOF"); 
                send(sock_accept,(const char*)&ph,sizeof(ph),0); 
                break; 
            } 
            else  
            { 
                FILE* fp = NULL; 
                fopen_s(&fp,input.c_str(),"rb"); 
                if(fp == NULL) 
                { 
                    cout<<"打開失敗"<<endl; 
                    continue; 
                } 
                else 
                { 
                    LONG32 sz = _filelength(_fileno(fp)); 
                    cout<<"文件打開成功,大小:"<<sz<<" Bytes"<<endl; 
                    PacketHeader ph; 
                    strcpy_s(ph.code,"PIC"); 
                    strcpy_s(ph.name,input.c_str()); 
                    ph.size = sz; 
                    send(sock_accept,(const char*)&ph,sizeof(ph),0); 
                    cout<<"已發送頭部信息"<<endl; 
 
                    int nSend = 0; 
                    char buffer[1024]; 
                    while(nSend < sz) 
                    { 
                        int nBytes = fread(buffer,sizeof(char),1024,fp); 
                        if(nBytes <= 0)                           
                            break;                   
                        send(sock_accept,buffer,nBytes,0); 
                        cout<<"已發送 "<<nBytes<<" Bytes"<<endl; 
                        nSend += nBytes; 
                    } 
                    cout<<"總計發送 "<<nSend<<" Bytes"<<endl; 
                    fclose(fp); 
                } 
            } 
        } 
        closesocket(sock_accept); 
    }catch(int which){ 
        if(which == 2) 
            closesocket(sock_listen); 
        if(which == 3) 
            closesocket(sock_accept); 
    } 
    WSACleanup(); 

客戶端代碼:

[cpp]
#include <WinSock.h> 
#pragma comment(lib,"ws2_32.lib") 
 
#define IP      "127.0.0.1" 
#define PORT    6666 
 
struct PacketHeader 

    char code[10];      // 指令:"EOF"=斷開連接  "PIC"=接收圖片 
    char name[50];      // 名字:包括後綴 
    LONG32 size;        // 大小:字節 
    PacketHeader() 
    { 
        memset(code,0,sizeof(code)); 
        memset(name,0,sizeof(name)); 
        size = 0; 
    } 
}; 
 
void client()  

    WSADATA wd; 
    int ret = WSAStartup(MAKEWORD(2,2),&wd); 
    if(ret != 0) 
    { 
        cout<<"Initialize Winsock Failed! "<<GetLastError()<<endl;; 
        return; 
    } 
    cout<<"WSAStartup OK"<<endl; 
 
    sockaddr_in addr_serv; 
    int sock; 
    try{ 
        sock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); 
        if(sock == SOCKET_ERROR) 
        { 
            cout<<"create socket failed! "<<GetLastError()<<endl; 
            throw 1; 
        } 
        cout<<"socket OK"<<endl; 
 
        memset((void*)&addr_serv,0,sizeof(sockaddr)); 
        addr_serv.sin_family = AF_INET; 
        addr_serv.sin_addr.S_un.S_addr = inet_addr(IP); 
        addr_serv.sin_port = htons(PORT); 
 
        ret = connect(sock,(sockaddr*)&addr_serv,sizeof(addr_serv)); 
        if(ret == SOCKET_ERROR) 
        { 
            cout<<"connect failed! "<<GetLastError()<<endl; 
            throw 2; 
        } 
        cout<<"connect OK"<<endl; 
 
        char buffer[1024]; 
        while(true) 
        { 
            int nRecv = recv(sock,buffer,1024,0); 
            if(nRecv <= 0) 
                continue; 
            else if(nRecv == sizeof(PacketHeader)) 
            { 
                PacketHeader ph; 
                memcpy_s(&ph,sizeof(ph),buffer,nRecv); 
                if(strcmp(ph.code,"EOF") == 0) 
                    break; 
                else if(strcmp(ph.code,"PIC") == 0) 
                { 
                    cout<<"文件名:"<<ph.name<<",大小:"<<ph.size<<endl; 
                    FILE* fp = NULL; 
                    fopen_s(&fp,ph.name,"wb"); 
                    if(fp == NULL) 
                    { 
                        cout<<"創建文件失敗"<<endl; 
                        break; 
                    } 
                    else 
                    { 
                        nRecv = 0; 
                        while(nRecv < ph.size) 
                        { 
                            int nBytes = recv(sock,buffer,1024,0); 
                            if(nBytes <= 0) 
                                break; 
                            cout<<"已接收 "<<nBytes<<" Bytes"<<endl; 
                            fwrite(buffer,sizeof(char),nBytes,fp); 
                            nRecv += nBytes; 
                        } 
                        cout<<"共接收 "<<nRecv<<" Bytes"<<endl; 
                        fclose(fp); 
                    } 
                } 
                else 
                { 
                    cout<<"頭部信息錯誤"<<endl; 
                    break; 
                } 
            } 
            else 
            { 
                buffer[nRecv] = '\0'; 
                cout<<buffer<<endl; 
            } 
        } 
        closesocket(sock); 
    }catch(int which){   
        if(which == 2) 
        closesocket(sock); 
    } 
    WSACleanup(); 

運行截圖:

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved