一个基本的网络通信问题,请大家帮忙看下啊~

时间:2022-12-04 07:45:47
1、客户端将设置好的参数发给服务器端
2、服务器端将状态信息返回给客户端
3、服务器端将处理好的结果发送给客户端

是否需要建立两条TCP连接呢?一条连接主管步骤1和2,一条主管3
是否需要两个线程?
那些设置过的参数,要用自定义的格式发送出去,是声明个结构体保存么?

都是些很基本的问题,可是希望能得到大家具体的指导。最好是如果大家有这样的例程,能否发给我一份呢?谢谢啊!
flowerseashine@yahoo.com.cn

3 个解决方案

#1


一个Socket连接来交换数据,
结构体填充好数据后,转成TCHAR*,然后发送出去,接收端再转换回结构体

#2


引用 1 楼 oyljerry 的回复:
一个Socket连接来交换数据,
结构体填充好数据后,转成TCHAR*,然后发送出去,接收端再转换回结构体

意思就是单个socket连接,单个线程么?为什么要转换成TCHAR*呢?

#3




网上看到的,希望对你有帮助,我感觉写的不错(我是还是比较菜)















TCP协议实现文件传输
 使用TCP协议实现传输文件
    程序分为发送端和接收端。首先在传输文件数据之前,发送端会把将装有文件名称和文件长度等
信息的数据包发送至接收端。接收端收到文件名称和文件长度信息后会创建好空白文件。接着开始传输
文件数据。下面介绍实现功能的主要过程:

1.创建套接字、绑定、监听、连接、接受连接
//创建TCP协议的套接字
    m_Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if(SOCKET_ERROR == m_Socket)
        AfxMessageBox("Create Socket Error! ", 0, 0);

//绑定与监听
    SOCKADDR_IN   addrSrv;   
    addrSrv.sin_addr.s_addr = inet_addr(sIP);
    addrSrv.sin_family   =   AF_INET;   
    addrSrv.sin_port   =   htons(Port);   
    int   ret   =   bind(m_Socket,   (SOCKADDR   *)&addrSrv,   sizeof(SOCKADDR));   
    if(ret==SOCKET_ERROR)   
        AfxMessageBox("Bind Socket Error!", 0, 0);

//连接
    SOCKADDR_IN ServerAddr;
    ServerAddr.sin_addr.s_addr = inet_addr(ServerAddr_in);
    ServerAddr.sin_family = AF_INET;
    ServerAddr.sin_port = htons(ServerPort);
    int Result = connect(m_Socket, (struct sockaddr*)&ServerAddr, sizeof(struct sockaddr));
    if(SOCKET_ERROR == Result)
        AfxMessageBox("Connet Failed!");

//接受连接
    SOCKADDR_IN ClientAddr;
    int len = sizeof(SOCKADDR_IN);
    SOCKET ClientSock = accept(m_Socket, (struct sockaddr*)&ClientAddr, &len);
    if(SOCKET_ERROR == ClientSock)
        AfxMessageBox("Accept Failed!");

2.声明宏和结构体
声明套接字缓冲区和一次发送文件数据的缓冲区大小
#define SOCKET_BUFF 80000    //套接字缓冲区大小
#define PACK_BUFF 50000        //数据包缓冲区大小


声明文件I/O缓冲区和最大文件路径长度
#define FILE_NAME_MAX 100       //文件路径最大长度
#define FILE_IO_BUFF PACK_BUFF    //文件IO缓冲区    


//文件信息
typedef struct _FileInfor    
{
    u_long ulFileLen;
    char sFileName[ FILE_NAME_MAX ];
}_FileInfor;

//数据包
typedef struct _DataPack
{
    char cType;        //'D'为数据  'M'为文件信息
    int nPackLen;
    char sContent[ PACK_BUFF ];            //数据包缓冲区
    u_long nPosition;                //数据在文件中的位置
    int nContentLen;                //数据字节数
    _FileInfor    FileInfor;        //文件信息
}_DataPack;



3.发送端
//发送线程需要的全局变量
char sPath[FILE_NAME_MAX];        //文件地址
u_long FileByteCount;            //文件大小
SOCKET ClientSocket;            //


(1)设置套接字发送缓冲区大小,在32位Windows XP环境下,系统为每个套接字分配的默认发送数据缓
冲区为8192字节。由于传输的文件很大,可能几十兆,或者更大。那么系统为每个套接字分配的默认
缓冲区显然过小。为此在创建套接字之后,需要修改套接字发送数据缓冲尺寸。在这里我修改为80k,
差不多可以够用了。
    //设置套接字发送缓冲区
    int nBuf = SOCKET_BUFF;
    int nBufLen = sizeof(nBuf);
    int nRe = setsockopt(ClientSock, SOL_SOCKET, SO_SNDBUF, (char*)&nBuf, nBufLen);//完成套接字与缓冲区的联系
    if(SOCKET_ERROR == nRe)
        AfxMessageBox("setsockopt error!");    
    //检查缓冲区是否设置成功
    nRe = getsockopt(ClientSock, SOL_SOCKET, SO_SNDBUF, (char*)&nBuf, &nBufLen);
    if(SOCKET_BUFF != nBuf)
        AfxMessageBox("检查缓冲区:setsockopt error!");

(2)测量文件大小并发送文件大小和名称给客户端

    首先使用C库函数对源文件进行测量
    //得到文件地址
    LPTSTR lpPath =     m_sPath.GetBuffer(    m_sPath.GetLength ());
    //打开文件
    FILE *File = fopen(lpPath, "rb"); 
    if(NULL == File)
        AfxMessageBox("打开文件失败!");
    //测量文件大小
    char Buff[PACK_BUFF];
    u_long ulFaceReadByte;
    FileByteCount = 0;
    fseek(File, 0, SEEK_SET);
    while(!feof(File))
    {
        ulFaceReadByte = fread(Buff, 1, 1, File);
        FileByteCount += ulFaceReadByte;
    }
    //关闭文件
    int nRe = fclose(File);
    if(nRe)
        AfxMessageBox("关闭文件失败!");
        
    此时以获取源文件的长度,我们将文件长度和文件名称放到数据包中,设置数据包为'M'类型。
    //打包
    _DataPack Pack;
    Pack.cType = 'M';
    Pack.nPackLen = sizeof(Pack);
    //取得文件名
    ZeroMemory(Pack.FileInfor.sFileName, FILE_NAME_MAX);
    GetFIieNameFromPath(lpPath, Pack.FileInfor.sFileName);
    Pack.FileInfor.ulFileLen = FileByteCount;
    
    接着使用send()将打包完成的数据包发送给接收端,把发送线程的全局变量初始化,并创建发送线
程,文件数据将由发送线程负责发送
    //发送数据包 文件大小和名称
    nRe = send(m_ClientSockFd.fd_array[0], (char*)&Pack, Pack.nPackLen, 0);
    if(SOCKET_ERROR == nRe)
            AfxMessageBox("Send File Size Failed!");
    //线程准备全局变量
    strcpy(sPath, m_sPath);
    ClientSocket = m_ClientSockFd.fd_array[0];
    //启动线程发送文件
    DWORD ID;
    m_hSendThread = CreateThread(0, 0, SendDataThrad, 0, 0, &ID);


(3)发送文件数据线程。先打开源文件,为了一次读取大量数据将文件缓冲区设置为FILE_IO_BUFF大小,
然后将读取的数据打包并发送。这样不断地读、不断地发送,直到将整个文件发送完为止。

DWORD __stdcall CServerDlg::SendDataThrad(LPVOID LpP)
{
    //打开文件
    FILE *File = fopen(sPath, "rb");
    if(NULL == File)
    {
        AfxMessageBox("SendDataThrad中打开文件失败!");
        return 1;
    }
    //设置文件缓冲区
    int nBuff = FILE_IO_BUFF;
    if(setvbuf(File, (char*)&nBuff, _IOFBF, sizeof(nBuff)))
        AfxMessageBox("设置文件缓冲区失败!");
    //读取文件数据并发送
    u_long ulFlagCount = 0;            //记录读了多少数据
    u_long FaceReadByte = 0;    //一次实际读取的字节数
    char sBuff[PACK_BUFF];    
    ZeroMemory(sBuff, PACK_BUFF);
    fseek(File, 0, SEEK_SET);
    while (!feof(File))
    {
        FaceReadByte = fread(sBuff, 1, PACK_BUFF, File);
        //打包
        _DataPack DataPack;
        DataPack.cType = 'D';
        DataPack.nPackLen = sizeof(DataPack);
        DataPack.nContentLen = FaceReadByte;
        CopyMemory(DataPack.sContent, sBuff, FaceReadByte);
        DataPack.nPosition = ulFlagCount;
        //发送
        int nResult = send(ClientSocket, (char*)&DataPack, DataPack.nPackLen, 0);
        if (SOCKET_ERROR == nResult)
        {
            AfxMessageBox("SendDataThrad中发送数据失败!");
        }else
            ulFlagCou2nt += FaceReadByte;        //记录发送字节数
    }
    AfxMessageBox("发送结束");
    //关闭
    int nRe = fclose(File);
    if(nRe)
        AfxMessageBox("SendDataThrad中关闭文件失败!");
    return 0;
}

4.接收端
//接收线程用的全局变量
_FileInfor FileInfor;        //文件信息
u_long ulWriteByte;            //记录总共写入的字节
char lpPath[FILE_NAME_MAX];    //文件路径
char sFilePathAndName[FILE_NAME_MAX];        //完整的文件路径

(1)设置套接字接收缓冲区大小。
//设置套接字接收缓冲区
    int nBuf = SOCKET_BUFF;
    int nBufLen = sizeof(nBuf);
    SOCKET ClientSock = m_Sock.GetSocket();
    int nRe = setsockopt(ClientSock, SOL_SOCKET, SO_RCVBUF, (char*)&nBuf, nBufLen);
    if(SOCKET_ERROR == nRe)
            AfxMessageBox("setsockopt error!");
    //检查缓冲区是否设置成功
    nRe = getsockopt(ClientSock, SOL_SOCKET, SO_RCVBUF, (char*)&nBuf, &nBufLen);
    if(SOCKET_BUFF != nBuf)
        AfxMessageBox("检查缓冲区:setsockopt error!");
        
(2)接收文件信息和文件数据线程。先判断数据包是属于文件信息还是文件类型,如果是文件信息就根
据信息创建空文件,如果是文件数据就将数据已追加的方式写进目的文件中。

DWORD __stdcall CClientDlg::ReceiveDataPro(LPVOID LpP)
{
    CSocket_Win32 *pCSock = (CSocket_Win32*)LpP;
    u_long ulWriteByteCount = 0;
    while (1)
    {
        _DataPack DataPack;
        ZeroMemory(&DataPack, sizeof(DataPack));
        if(!(*pCSock).Receive(&DataPack, sizeof(DataPack)))
        {
            AfxMessageBox("Receive DataPack Failed!");
        }
        //判断数据包类型
        if('M' == DataPack.cType)    //包为文件信息
        {
            //接收文件信息
            FileInfor.ulFileLen = DataPack.FileInfor.ulFileLen;  //获取文件长度
            strcpy(FileInfor.sFileName, DataPack.FileInfor.sFileName); //获取文件名称
            //得到文件目录
            char sFilePath[FILE_NAME_MAX];
            ZeroMemory(sFilePath, FILE_NAME_MAX);
            strcpy(sFilePath, lpPath);
            strcat(sFilePath, FileInfor.sFileName);
            strcat(sFilePathAndName, sFilePath);    //保存完整的文件路径
            //创建文件
            SECURITY_ATTRIBUTES attr;
            attr.nLength = FileInfor.ulFileLen;
            attr.lpSecurityDescriptor = NULL;
            HANDLE hRe = CreateFile(sFilePath, GENERIC_WRITE, FILE_SHARE_WRITE, &attr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
            if(INVALID_HANDLE_VALUE == hRe)
                AfxMessageBox("创建文件失败!");
            bool bRe = ::CloseHandle(hRe);
            //可以开始接受文件
            bIsStartReceive = true;
        }else if('D' == DataPack.cType)        //包为文件数据
        {
            //打开文件
            char sPath[FILE_NAME_MAX];
            strcpy(sPath, sFilePathAndName);
            FILE *File = fopen(sPath, "ab");
            if(0 == File)
                AfxMessageBox("打开文件失败!");
            //设置文件缓冲区
            int nBuff = FILE_IO_BUFF;
            if(setvbuf(File, (char*)&nBuff, _IOFBF, sizeof(nBuff)))
                AfxMessageBox("设置文件缓冲区失败!");
            //定位文件
            u_long nPosition = DataPack.nPosition;
            int nRe = fseek(File, nPosition, SEEK_SET);
            if(nRe)
                AfxMessageBox("SendDataThrad中定位失败!");
            //写文件
            u_long nNumberOfBytesWritten = fwrite(&DataPack.sContent, 1, DataPack.nContentLen, File);
            if(DataPack.nContentLen != nNumberOfBytesWritten)
                AfxMessageBox("写文件失败!");
            else
            {
                ulWriteByteCount += nNumberOfBytesWritten;
            }
            fflush(File);                                //清除文件缓冲区
            //关闭文件
            nRe = fclose(File);
            if(nRe)
                AfxMessageBox("关闭文件失败!");

            if(ulWriteByteCount >= FileInfor.ulFileLen)
            {
                AfxMessageBox("接收结束");
                break;
            }    
        }
    }
    return 0;
}

#1


一个Socket连接来交换数据,
结构体填充好数据后,转成TCHAR*,然后发送出去,接收端再转换回结构体

#2


引用 1 楼 oyljerry 的回复:
一个Socket连接来交换数据,
结构体填充好数据后,转成TCHAR*,然后发送出去,接收端再转换回结构体

意思就是单个socket连接,单个线程么?为什么要转换成TCHAR*呢?

#3




网上看到的,希望对你有帮助,我感觉写的不错(我是还是比较菜)















TCP协议实现文件传输
 使用TCP协议实现传输文件
    程序分为发送端和接收端。首先在传输文件数据之前,发送端会把将装有文件名称和文件长度等
信息的数据包发送至接收端。接收端收到文件名称和文件长度信息后会创建好空白文件。接着开始传输
文件数据。下面介绍实现功能的主要过程:

1.创建套接字、绑定、监听、连接、接受连接
//创建TCP协议的套接字
    m_Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if(SOCKET_ERROR == m_Socket)
        AfxMessageBox("Create Socket Error! ", 0, 0);

//绑定与监听
    SOCKADDR_IN   addrSrv;   
    addrSrv.sin_addr.s_addr = inet_addr(sIP);
    addrSrv.sin_family   =   AF_INET;   
    addrSrv.sin_port   =   htons(Port);   
    int   ret   =   bind(m_Socket,   (SOCKADDR   *)&addrSrv,   sizeof(SOCKADDR));   
    if(ret==SOCKET_ERROR)   
        AfxMessageBox("Bind Socket Error!", 0, 0);

//连接
    SOCKADDR_IN ServerAddr;
    ServerAddr.sin_addr.s_addr = inet_addr(ServerAddr_in);
    ServerAddr.sin_family = AF_INET;
    ServerAddr.sin_port = htons(ServerPort);
    int Result = connect(m_Socket, (struct sockaddr*)&ServerAddr, sizeof(struct sockaddr));
    if(SOCKET_ERROR == Result)
        AfxMessageBox("Connet Failed!");

//接受连接
    SOCKADDR_IN ClientAddr;
    int len = sizeof(SOCKADDR_IN);
    SOCKET ClientSock = accept(m_Socket, (struct sockaddr*)&ClientAddr, &len);
    if(SOCKET_ERROR == ClientSock)
        AfxMessageBox("Accept Failed!");

2.声明宏和结构体
声明套接字缓冲区和一次发送文件数据的缓冲区大小
#define SOCKET_BUFF 80000    //套接字缓冲区大小
#define PACK_BUFF 50000        //数据包缓冲区大小


声明文件I/O缓冲区和最大文件路径长度
#define FILE_NAME_MAX 100       //文件路径最大长度
#define FILE_IO_BUFF PACK_BUFF    //文件IO缓冲区    


//文件信息
typedef struct _FileInfor    
{
    u_long ulFileLen;
    char sFileName[ FILE_NAME_MAX ];
}_FileInfor;

//数据包
typedef struct _DataPack
{
    char cType;        //'D'为数据  'M'为文件信息
    int nPackLen;
    char sContent[ PACK_BUFF ];            //数据包缓冲区
    u_long nPosition;                //数据在文件中的位置
    int nContentLen;                //数据字节数
    _FileInfor    FileInfor;        //文件信息
}_DataPack;



3.发送端
//发送线程需要的全局变量
char sPath[FILE_NAME_MAX];        //文件地址
u_long FileByteCount;            //文件大小
SOCKET ClientSocket;            //


(1)设置套接字发送缓冲区大小,在32位Windows XP环境下,系统为每个套接字分配的默认发送数据缓
冲区为8192字节。由于传输的文件很大,可能几十兆,或者更大。那么系统为每个套接字分配的默认
缓冲区显然过小。为此在创建套接字之后,需要修改套接字发送数据缓冲尺寸。在这里我修改为80k,
差不多可以够用了。
    //设置套接字发送缓冲区
    int nBuf = SOCKET_BUFF;
    int nBufLen = sizeof(nBuf);
    int nRe = setsockopt(ClientSock, SOL_SOCKET, SO_SNDBUF, (char*)&nBuf, nBufLen);//完成套接字与缓冲区的联系
    if(SOCKET_ERROR == nRe)
        AfxMessageBox("setsockopt error!");    
    //检查缓冲区是否设置成功
    nRe = getsockopt(ClientSock, SOL_SOCKET, SO_SNDBUF, (char*)&nBuf, &nBufLen);
    if(SOCKET_BUFF != nBuf)
        AfxMessageBox("检查缓冲区:setsockopt error!");

(2)测量文件大小并发送文件大小和名称给客户端

    首先使用C库函数对源文件进行测量
    //得到文件地址
    LPTSTR lpPath =     m_sPath.GetBuffer(    m_sPath.GetLength ());
    //打开文件
    FILE *File = fopen(lpPath, "rb"); 
    if(NULL == File)
        AfxMessageBox("打开文件失败!");
    //测量文件大小
    char Buff[PACK_BUFF];
    u_long ulFaceReadByte;
    FileByteCount = 0;
    fseek(File, 0, SEEK_SET);
    while(!feof(File))
    {
        ulFaceReadByte = fread(Buff, 1, 1, File);
        FileByteCount += ulFaceReadByte;
    }
    //关闭文件
    int nRe = fclose(File);
    if(nRe)
        AfxMessageBox("关闭文件失败!");
        
    此时以获取源文件的长度,我们将文件长度和文件名称放到数据包中,设置数据包为'M'类型。
    //打包
    _DataPack Pack;
    Pack.cType = 'M';
    Pack.nPackLen = sizeof(Pack);
    //取得文件名
    ZeroMemory(Pack.FileInfor.sFileName, FILE_NAME_MAX);
    GetFIieNameFromPath(lpPath, Pack.FileInfor.sFileName);
    Pack.FileInfor.ulFileLen = FileByteCount;
    
    接着使用send()将打包完成的数据包发送给接收端,把发送线程的全局变量初始化,并创建发送线
程,文件数据将由发送线程负责发送
    //发送数据包 文件大小和名称
    nRe = send(m_ClientSockFd.fd_array[0], (char*)&Pack, Pack.nPackLen, 0);
    if(SOCKET_ERROR == nRe)
            AfxMessageBox("Send File Size Failed!");
    //线程准备全局变量
    strcpy(sPath, m_sPath);
    ClientSocket = m_ClientSockFd.fd_array[0];
    //启动线程发送文件
    DWORD ID;
    m_hSendThread = CreateThread(0, 0, SendDataThrad, 0, 0, &ID);


(3)发送文件数据线程。先打开源文件,为了一次读取大量数据将文件缓冲区设置为FILE_IO_BUFF大小,
然后将读取的数据打包并发送。这样不断地读、不断地发送,直到将整个文件发送完为止。

DWORD __stdcall CServerDlg::SendDataThrad(LPVOID LpP)
{
    //打开文件
    FILE *File = fopen(sPath, "rb");
    if(NULL == File)
    {
        AfxMessageBox("SendDataThrad中打开文件失败!");
        return 1;
    }
    //设置文件缓冲区
    int nBuff = FILE_IO_BUFF;
    if(setvbuf(File, (char*)&nBuff, _IOFBF, sizeof(nBuff)))
        AfxMessageBox("设置文件缓冲区失败!");
    //读取文件数据并发送
    u_long ulFlagCount = 0;            //记录读了多少数据
    u_long FaceReadByte = 0;    //一次实际读取的字节数
    char sBuff[PACK_BUFF];    
    ZeroMemory(sBuff, PACK_BUFF);
    fseek(File, 0, SEEK_SET);
    while (!feof(File))
    {
        FaceReadByte = fread(sBuff, 1, PACK_BUFF, File);
        //打包
        _DataPack DataPack;
        DataPack.cType = 'D';
        DataPack.nPackLen = sizeof(DataPack);
        DataPack.nContentLen = FaceReadByte;
        CopyMemory(DataPack.sContent, sBuff, FaceReadByte);
        DataPack.nPosition = ulFlagCount;
        //发送
        int nResult = send(ClientSocket, (char*)&DataPack, DataPack.nPackLen, 0);
        if (SOCKET_ERROR == nResult)
        {
            AfxMessageBox("SendDataThrad中发送数据失败!");
        }else
            ulFlagCou2nt += FaceReadByte;        //记录发送字节数
    }
    AfxMessageBox("发送结束");
    //关闭
    int nRe = fclose(File);
    if(nRe)
        AfxMessageBox("SendDataThrad中关闭文件失败!");
    return 0;
}

4.接收端
//接收线程用的全局变量
_FileInfor FileInfor;        //文件信息
u_long ulWriteByte;            //记录总共写入的字节
char lpPath[FILE_NAME_MAX];    //文件路径
char sFilePathAndName[FILE_NAME_MAX];        //完整的文件路径

(1)设置套接字接收缓冲区大小。
//设置套接字接收缓冲区
    int nBuf = SOCKET_BUFF;
    int nBufLen = sizeof(nBuf);
    SOCKET ClientSock = m_Sock.GetSocket();
    int nRe = setsockopt(ClientSock, SOL_SOCKET, SO_RCVBUF, (char*)&nBuf, nBufLen);
    if(SOCKET_ERROR == nRe)
            AfxMessageBox("setsockopt error!");
    //检查缓冲区是否设置成功
    nRe = getsockopt(ClientSock, SOL_SOCKET, SO_RCVBUF, (char*)&nBuf, &nBufLen);
    if(SOCKET_BUFF != nBuf)
        AfxMessageBox("检查缓冲区:setsockopt error!");
        
(2)接收文件信息和文件数据线程。先判断数据包是属于文件信息还是文件类型,如果是文件信息就根
据信息创建空文件,如果是文件数据就将数据已追加的方式写进目的文件中。

DWORD __stdcall CClientDlg::ReceiveDataPro(LPVOID LpP)
{
    CSocket_Win32 *pCSock = (CSocket_Win32*)LpP;
    u_long ulWriteByteCount = 0;
    while (1)
    {
        _DataPack DataPack;
        ZeroMemory(&DataPack, sizeof(DataPack));
        if(!(*pCSock).Receive(&DataPack, sizeof(DataPack)))
        {
            AfxMessageBox("Receive DataPack Failed!");
        }
        //判断数据包类型
        if('M' == DataPack.cType)    //包为文件信息
        {
            //接收文件信息
            FileInfor.ulFileLen = DataPack.FileInfor.ulFileLen;  //获取文件长度
            strcpy(FileInfor.sFileName, DataPack.FileInfor.sFileName); //获取文件名称
            //得到文件目录
            char sFilePath[FILE_NAME_MAX];
            ZeroMemory(sFilePath, FILE_NAME_MAX);
            strcpy(sFilePath, lpPath);
            strcat(sFilePath, FileInfor.sFileName);
            strcat(sFilePathAndName, sFilePath);    //保存完整的文件路径
            //创建文件
            SECURITY_ATTRIBUTES attr;
            attr.nLength = FileInfor.ulFileLen;
            attr.lpSecurityDescriptor = NULL;
            HANDLE hRe = CreateFile(sFilePath, GENERIC_WRITE, FILE_SHARE_WRITE, &attr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
            if(INVALID_HANDLE_VALUE == hRe)
                AfxMessageBox("创建文件失败!");
            bool bRe = ::CloseHandle(hRe);
            //可以开始接受文件
            bIsStartReceive = true;
        }else if('D' == DataPack.cType)        //包为文件数据
        {
            //打开文件
            char sPath[FILE_NAME_MAX];
            strcpy(sPath, sFilePathAndName);
            FILE *File = fopen(sPath, "ab");
            if(0 == File)
                AfxMessageBox("打开文件失败!");
            //设置文件缓冲区
            int nBuff = FILE_IO_BUFF;
            if(setvbuf(File, (char*)&nBuff, _IOFBF, sizeof(nBuff)))
                AfxMessageBox("设置文件缓冲区失败!");
            //定位文件
            u_long nPosition = DataPack.nPosition;
            int nRe = fseek(File, nPosition, SEEK_SET);
            if(nRe)
                AfxMessageBox("SendDataThrad中定位失败!");
            //写文件
            u_long nNumberOfBytesWritten = fwrite(&DataPack.sContent, 1, DataPack.nContentLen, File);
            if(DataPack.nContentLen != nNumberOfBytesWritten)
                AfxMessageBox("写文件失败!");
            else
            {
                ulWriteByteCount += nNumberOfBytesWritten;
            }
            fflush(File);                                //清除文件缓冲区
            //关闭文件
            nRe = fclose(File);
            if(nRe)
                AfxMessageBox("关闭文件失败!");

            if(ulWriteByteCount >= FileInfor.ulFileLen)
            {
                AfxMessageBox("接收结束");
                break;
            }    
        }
    }
    return 0;
}