设为首页 加入收藏

TOP

使用TCP协议实现文件传输(一)
2013-05-14 09:22:41 来源: 作者: 【 】 浏览:590
Tags:使用 TCP 协议 实现 文件 传输


    3、关闭套接字
    释放服务
    源程序:
    【1】服务器端:
    头文件:
    [cpp]
    /*server.h*/
    #pragma comment(lib, "WS2_32")
    #include <WinSock2.h>
    #include <iostream>
    #include <assert.h>
    #include<Windows.h>
    #ifndef COMMONDEF_H
    #define COMMONDEF_H
    #define MAX_PACKET_SIZE   10240    // 数据包的最大长度,单位是sizeof(char)
    #define MAXFILEDIRLENGTH 256     // 存放文件路径的最大长度
    #define PORT     4096    // 端口号
    //#define SERVER_IP    "127.0.0.1" // server端的IP地址
    // 各种消息的宏定义
    #define INVALID_MSG      -1   // 无效的消息标识
    #define MSG_FILENAME     1   // 文件的名称
    #define MSG_FILELENGTH     2   // 传送文件的长度
    #define MSG_CLIENT_READY    3   // 客户端准备接收文件
    #define MSG_FILE      4   // 传送文件
    #define MSG_SENDFILESUCCESS    5   // 传送文件成功
    #define MSG_OPENFILE_ERROR    10   // 打开文件失败,可能是文件路径错误找不到文件等原因
    #define MSG_FILEALREADYEXIT_ERROR 11   // 要保存的文件已经存在了
    class CCSDef
    {
    public:
    #pragma pack(1)      // 使结构体的数据按照1字节来对齐,省空间
    // 消息头
    struct TMSG_HEADER
    {
    char    cMsgID;    // 消息标识
    TMSG_HEADER(char MsgID = INVALID_MSG)
    : cMsgID(MsgID)
    {
    }
    };
    // 请求传送的文件名
    // 客户端传给服务器端的是全路径名称
    // 服务器传回给客户端的是文件名
    struct TMSG_FILENAME : public TMSG_HEADER
    {
    char szFileName[256];   // 保存文件名的字符数组
    TMSG_FILENAME()
    : TMSG_HEADER(MSG_FILENAME)
    {
    }
    };
    // 传送文件长度
    struct TMSG_FILELENGTH : public TMSG_HEADER
    {
    long lLength;
    TMSG_FILELENGTH(long length)
    : TMSG_HEADER(MSG_FILELENGTH), lLength(length)
    {
    }
    };
    // Client端已经准备好了,要求Server端开始传送文件
    struct TMSG_CLIENT_READY : public TMSG_HEADER
    {
    TMSG_CLIENT_READY()
    : TMSG_HEADER(MSG_CLIENT_READY)
    {
    }
    };
    // 传送文件
    struct TMSG_FILE : public TMSG_HEADER
    {
    union     // 采用union保证了数据包的大小不大于MAX_PACKET_SIZE * sizeof(char)
    {
    char szBuff[MAX_PACKET_SIZE];
    struct
    {
    int nStart;
    int nSize;
    char szBuff[MAX_PACKET_SIZE - 2 * sizeof(int)];
    }tFile;
    };
    TMSG_FILE()
    : TMSG_HEADER(MSG_FILE)
    {
    }
    };
    // 传送文件成功
    struct TMSG_SENDFILESUCCESS : public TMSG_HEADER
    {
    TMSG_SENDFILESUCCESS()
    : TMSG_HEADER(MSG_SENDFILESUCCESS)
    {
    }
    };
    // 传送出错信息,包括:
    // MSG_OPENFILE_ERROR:打开文件失败
    // MSG_FILEALREADYEXIT_ERROR:要保存的文件已经存在了
    struct TMSG_ERROR_MSG : public TMSG_HEADER
    {
    TMSG_ERROR_MSG(char cErrorMsg)
    : TMSG_HEADER(cErrorMsg)
    {
    }
    };
    #pragma pack()
    };
    #endif
    cpp文件:
    [cpp]
    /*Server.cpp*/
    #include"Server.h"
    char g_szNewFileName[MAXFILEDIRLENGTH];
    char g_szBuff[MAX_PACKET_SIZE + 1];
    long g_lLength;
    char* g_pBuff = NULL;
    //初始化socket库
    bool InitSocket();
    //关闭socket库
    bool CloseSocket();
    //解析消息并进行相应的处理
    bool ProcessMsg(SOCKET sClient);
    //监听Client消息
    void ListenToClient();
    //打开文件
    bool OpenFile(CCSDef::TMSG_HEADER* pMagHeader,SOCKET sClient);
    //传送文件
    bool SendFile(SOCKET sClient);
    //读取文件进缓冲区
    bool ReadFile(SOCKET sClient);
    int main()
    {
    while(1)
    {
    InitSocket();
    ListenToClient();
    CloseSocket();
    system("del E:\\test1.A_exp");
    }
    //system("pause");
    return 0;
    }
    //初始化socket库
    bool InitSocket()
    {
    WSADATA wsaData;
    WORD socketVersion=MAKEWORD(2,2);
    if(::WSAStartup(socketVersion,&wsaData)!=0)
    {//初始化WinSock服务
    printf("Init socket dll error\n");
    return false;
    }
    return true;
    }
    //关闭socket库
    bool CloseSocket()
    {//释放winsock库
    ::WSACleanup();
    if(g_pBuff != NULL)
    {
    delete [] g_pBuff;
    g_pBuff = NULL;
    }
    return true;
    }
    //解析消息并进行相应的处理
    bool ProcessMsg(SOCKET sClient)
    {
    //从套接口中接收数据,返回copy的字节数
    int nRecv = ::recv(sClient,g_szBuff,MAX_PACKET_SIZE+1,0);
    if(nRecv>0)
    {
    g_szBuff[nRecv]='\0';
    }
    //解析命令
    CCSDef::TMSG_HEADER* pMsgHeader=(CCSDef::TMSG_HEADER*)g_szBuff;
    switch(pMsgHeader->cMsgID)
    {
    case MSG_FILENAME://文件名
    {
    OpenFile(pMsgHeader,sClient);
    }
    break;
    case MSG_CLIENT_READY://客户端已准备完毕,开始传送文件
    {
    SendFile(sClient);
    }
    break;
    case MSG_SENDFILESUCCESS://传送文件成功
    {
    printf("Send File Success!\n");
    return false;
    }
    break;
    case MSG_FILEALREADYEXIT_ERROR://要保存的文件已经存在
    {
    printf("The file ready to send already exit!\n");
    return false;
    }
    break;
    }
    return true;
    }
    //监听Client消息
    void ListenToClient()
    {
    //创建套接字
    SOCKET sListen = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if(sListen == SOCKET_ERROR)
    {
    printf("Init Socket Error!\n");
    return;
    }
    //绑定socket
    sockaddr_in sin;
    sin.sin_family=AF_INET;
    sin.sin_port=htons(PORT);
    sin.sin_addr.S_un.S_addr=INADDR_ANY;
    if (::bind(sListen, (LPSOCKADDR)&sin, sizeof(sockaddr_in)) == SOCKET_ERROR)
    {
    printf("Bind Error!\n");
    return;
    }
    // 设置socket进入监听状态
    if(::listen(sListen,10)==SOCKET_ERROR)
    {
    printf("Listen Error!\n");
    return;
    }

          

首页 上一页 1 2 3 4 下一页 尾页 1/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇找出最小元素A与B的联盟 下一篇set和multiset的内部结构

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: