转载:UDP文件传输的实现

来源:互联网 发布:淘宝如何申请退款 编辑:程序博客网 时间:2024/05/19 03:45

文章来自:http://blog.csdn.net/andyzhshg/article/details/3565177

 

 

目录

一、对界面插件设置...2

二、功能实现...3

1、点击查找文件按钮,在待发送文件编辑框中出现文件及路径名...3

2、点击发送文件按钮,判断IP地址是否为空,编辑框中文件路径是否正确,文件是否正在发送中。    3

1)、Dlg类中添加公共变量...3

2)双击“发送文件”按钮,添加消息响应函数,在其中添加:...3

3、创建套接字,用来文件传输...4

1)、创建套接字...4

2)在Dlg.cpp初始化函数中添加...4

4、向对方IP地址主机发送消息,是否同意接收...5

5、在Dlg.cpp中创建一个线程,用来接收数据的线程...6

6、建立一个消息,根据传输来的数据的第一个字节的内容进行不同的处理...9

 

 

一、对界面插件设置

1IP控件,IDIDC_IP_ADDR,变量名为:m_IPAddr

2、待发送文件路径:IDIDC_FILE_PATH,变量名为:m_filePath

3、查找文件按钮,IDIDC_FIND_FILE

4、发送进度(即第一个)进程控制条,IDIDC_PROGRESS_SEND,变量名为m_progress

5、接收进度(即第二个)进程控制条,IDIDC_PROGRESS_RECV,变量名为:m_progress_r

6、发送文件按钮,ID为:IDOK

7、退出按钮,IDIDCANCEL

8、发送进度,IDIDC_SEND,变量名为:m_send

9、接收进度,IDIDC_RECV。变量名为:m_recv

二、

1、点击查找文件按钮,在待发送文件编辑框中出现文件及路径名

双击“查找文件”按钮,添加消息响应函数,添加内容为:

CFileDialog openFile(true);

        if (IDOK == openFile.DoModal())

        {

                  m_filePath = openFile.GetPathName();

                  UpdateData(false);

        }

2、点击发送文件按钮,判断IP地址是否为空,编辑框中文件路径是否正确,文件是否正在发送中。

1)、Dlg类中添加公共变量

bool m_posting,并在Dlg.cpp中的CUdpFileTransportDlg::CUdpFileTransportDlg(CWnd* pParent /*=NULL*/)

        : CDialog(CUdpFileTransportDlg::IDD, pParent)

函数内设置初始值为m_posting=false。同时在其内设置         

m_recv = _T("发送进度");

        m_send = _T("接受进度");

2)双击“发送文件”按钮,添加消息响应函数,在其中添加:

        if (m_posting)

        {

                  MessageBox("数据发送中,请稍候再试。");

                  return;

        }

 

        UpdateData();

 

        if (m_filePath == "")

        {

                  MessageBox("请输入要发送的文件路径!");

                  return;

        }

        

        if (m_IPAddr.IsBlank())

        {

                  MessageBox("请添入接收者的IP地址。");

                  return;

        }

 

        WIN32_FIND_DATA FindFileData;

 

        if (INVALID_HANDLE_VALUE == FindFirstFile(m_filePath, &FindFileData))

        {

                  MessageBox("文件路径错误或文件不存在!\n请重新指定文件路径。");

                  return;

        }

 

3、创建套接字,用来文件传输

1)、创建套接字

Dlg类中添加private变量SOCKET m_socket;

添加相应的库文件

Dlg.cpp#pragma comment (lib,”Ws2_32.lib”)

StdAfx.h中添加#include <Afxsock.h>

2)在Dlg.cpp初始化函数中添加

 

BOOL CUdpFileTransportDlg::OnInitDialog()

{

        CDialog::OnInitDialog();

中添加:

 

/***********************************************************************/

        m_socket=socket(AF_INET,SOCK_DGRAM,0);

        if(INVALID_SOCKET==m_socket)

        {

                  MessageBox("套接字创建失败!");

                  return FALSE;

        }

        SOCKADDR_IN addrSock;

        addrSock.sin_family=AF_INET;

        addrSock.sin_port=htons(6800);

        addrSock.sin_addr.S_un.S_addr=htonl(INADDR_ANY);

 

        int retval;

//m_socket套接字绑定到本地主机上

 

        retval=bind(m_socket,(SOCKADDR*)&addrSock,sizeof(SOCKADDR));

        if(SOCKET_ERROR==retval)

        {

                  closesocket(m_socket);

                  MessageBox("绑定失败!");

                  return FALSE;

        }

 

4、向对方IP地址主机发送消息,是否同意接收

1)、在Dlg类中添加private变量FILE* m_file;

(2)、该文件发送是这样的,将文件分成256次发送,m_nSend用来计数第几次发送

Dlg类中添加public变量int m_nSend

3)、Dlg类中设定int变量m_nFileSize_s,用来记录文件的大小。

(4) 加载套接字库在InitInstance()中,调用AfxSocketInit(),添加内容为:

 

在发送按钮中继续添加:

        DWORD dwIP;

        m_IPAddr.GetAddress(dwIP);

 

        SOCKADDR_IN addrTo;

        addrTo.sin_family=AF_INET;

        addrTo.sin_port=htons(6800);

        addrTo.sin_addr.S_un.S_addr=htonl(dwIP);

 

        char sendBuf[0x112];

        int i;

 

        //通信头,申请发送

        sendBuf[0] = 'H';

 

        for (i = 1; i <= 0x100 && FindFileData.cFileName[i-1] != '\0'; i++)

                  sendBuf[i] = FindFileData.cFileName[i-1];

        sendBuf[i] = '\0';

 

        _itoa(FindFileData.nFileSizeLow, &sendBuf[0x101], 10);

        sendBuf[0x111] = '\0';

        //把文件名及传送文件的大小的信息发送过去

        sendto(m_socket, sendBuf, 0x112, 0,

                  (SOCKADDR*)&addrTo, sizeof(SOCKADDR));

 

        if (!(m_file = fopen(m_filePath, "rb")))

        {

                  MessageBox("读取文件失败!");

        }

        m_nSend = 0;

//获取发送文件大小

        m_nFileSize_s = FindFileData.nFileSizeLow;

//设置进度条范围

        m_progress.SetRange(0, m_nFileSize_s/0x100+1);

        m_posting = true;

 

5、在Dlg.cpp中创建一个线程,用来接收数据的线程

Dlg.cpp中添加结构体

/////////////////////////////////////////////////////////////////////////////

// CFilePosterDlg message handlers

struct RECVPARAM

{

        HWND hWnd;

        SOCKET sock;

};

Dlg.cpp

BOOL CFilePosterDlg::OnInitDialog()

{

        CDialog::OnInitDialog();

中添加:

        //产生一个用于接收数据的线程

        struct RECVPARAM *pRecvParam=new RECVPARAM;

        pRecvParam->sock=m_socket;

        pRecvParam->hWnd=m_hWnd;

        HANDLE hThread=CreateThread(NULL,0,RecvProc,(LPVOID)pRecvParam,0,NULL);

        CloseHandle(hThread);

/**************************************************************************/

 

Dlg类中添加一个成员函数RecvProc();

//接收线程的回调函数

static DWORD WINAPI RecvProc(LPVOID lpParameter);

 

///////////////////////////////////////////////////////////////////

/*

 

A要发文件给BA首先发送的内容第一个字母为‘H’,等待B的反应;

B若同意接收文件,返回内容‘R’,否则返回‘D’,A停止发送;

B返回给A的内容为'R',A发送数据的第一个字节内容为‘F,

A发送即将结束,A发送数据的第一个字节内容为'E'

 

 

*/

//////////////////////////////////////////////////////////////////

 

 

//接收线程的回调函数

DWORD WINAPI CUdpFileTransportDlg::RecvProc(LPVOID lpParameter)

{

        SOCKET sock=((RECVPARAM*)lpParameter)->sock;

        HWND hWnd=((RECVPARAM*)lpParameter)->hWnd;

        delete lpParameter;        

 

        SOCKADDR_IN addrFrom;

        int len=sizeof(SOCKADDR);

        char recvBuf[0x112];                //256+17字节的缓冲

        char fileName[0x100];

        int retval, i;

        FILE* file = NULL;

 

        while(TRUE)

        {

                  //接收发来的0x112个字符数据

                  retval=recvfrom(sock,recvBuf,0x112,0,(SOCKADDR*)&addrFrom,&len);

                  

                  if(SOCKET_ERROR == retval)

                           break;

 

                  if (recvBuf[0] == 'R')

                  {

                           //通信头,对方同意接受

                           char wParam = 'R';

                           ::PostMessage(hWnd, WM_READY_TO_RECEIVE, (WPARAM)&wParam, 0);

                  }

                  else if (recvBuf[0] == 'D')

                  {

                           //通信头,对方拒绝接受

                           char wParam = 'D';

                           ::PostMessage(hWnd, WM_READY_TO_RECEIVE, (WPARAM)&wParam, 0);

                  }

                  else if (recvBuf[0] == 'H')

                  {

                           //通信头,对方申请发送文件     

                           for (i = 1; i <= 0x100 && recvBuf[i] != '\0'; i++)        //256字节用于存储文件名

                                    fileName[i-1] = recvBuf[i];

                           fileName[i-1] = '\0';

                           CString recvMsg;

                           //获得传输的文件大小

                           nFileSize = atoi(&recvBuf[0x101]);

                           float fileSize=nFileSize*1.0/(1024*1024);

                           recvMsg.Format("收到来自于(%s)的文件:%s\n文件大小:%.4fM字节\n是否接收?",        inet_ntoa(addrFrom.sin_addr), fileName, fileSize);                          

                           if (IDOK == AfxMessageBox(recvMsg, MB_OKCANCEL))

                           {

                                    //同意接收,弹出对话框

                                   CFileDialog saveDlg(false, NULL, fileName);

                                    //同意保存文件

                                    if (IDOK == saveDlg.DoModal())

                                    {

                                              if (!(file = fopen(saveDlg.GetPathName(), "wb")))

                                              {

                                                       AfxMessageBox("创建本地文件失败!");

                                                       continue;

                                              }

                                    

                                              char wParam = 'H';

                                              ::PostMessage(hWnd, WM_READY_TO_RECEIVE, (WPARAM)&wParam, (LPARAM)&addrFrom);                                          

                                    }

                                    else

                                              //不同意保存文件

                                    {

                                              char wParam = 'C';

                                              ::PostMessage(hWnd, WM_READY_TO_RECEIVE, (WPARAM)&wParam, (LPARAM)&addrFrom);

                                    }

                           }

                           else

                                    //不同意接收

                           {

                                    char wParam = 'C';

                                    ::PostMessage(hWnd, WM_READY_TO_RECEIVE, (WPARAM)&wParam, (LPARAM)&addrFrom);

                           }

 

                  }

                  else if (recvBuf[0] == 'F')

                  {

                           //己方已同意接收,接收数据块

                           fwrite(&recvBuf[0x12], 1, 0x100, file);

                           char wParam = 'F';

                           ::PostMessage(hWnd, WM_READY_TO_RECEIVE, (WPARAM)&wParam, (LPARAM)&addrFrom);

                  }

                  else if (recvBuf[0] == 'E')

                  {

                           //己方已同意接收,开始接收文件尾块

                           int bufSize = atoi(&recvBuf[1]);

                           fwrite(&recvBuf[0x12], 1, bufSize, file);

                  

                           fclose(file);

                           char wParam = 'E';

                           ::PostMessage(hWnd, WM_READY_TO_RECEIVE, (WPARAM)&wParam, (LPARAM)&addrFrom);

                  }

                  else

                           AfxMessageBox("传送数据过程中出现错误!");

        }

        return (DWORD)NULL;

}

6、建立一个消息,根据传输来的数据的第一个字节的内容进行不同的处理

1)在Dlgprotected//}}AFX_MSG下添加

        afx_msg void OnReadyToRecv(WPARAM wParam,LPARAM lParam);

(2)BEGIN_MESSAGE_MAP(CFilePosterDlg, CDialog)    //}}AFX_MSG_MAP下添加

ON_MESSAGE(WM_READY_TO_RECEIVE, OnReadyToRecv)         //自定义消息,用于分块发送文件

3)在Dlg.h中添加

#define    WM_READY_TO_RECEIVE WM_USER+1

4)、定义一个int变量,用来存储接收的文件大小

static int nFileSize;

(5)定义一个消息响应函数

//消息响应函数,每响应一次发送一段数据

void CUdpFileTransportDlg::OnReadyToRecv(WPARAM wParam,LPARAM lParam)

{

        char sendBuf[0x112];

        DWORD dwIP;

        m_IPAddr.GetAddress(dwIP);

 

        SOCKADDR_IN addrTo;

        addrTo.sin_family=AF_INET;

        addrTo.sin_port=htons(6800);

        addrTo.sin_addr.S_un.S_addr=htonl(dwIP);

 

 

        int nRead;

 

        switch (*(char*)wParam)

        {

        //对方拒绝接受

        case 'D':

                  MessageBox("对方拒绝接受你发送的文件!");

                  fclose(m_file);

                  m_posting = false;

                  break;

        //对方同意接受

        case 'R':

                  nRead = fread(&sendBuf[0x12], 1, 0x100, m_file);

                  //发送到文件结尾

                  if (nRead < 0x100)

                  {

                           //通信头,文件尾发送

                           sendBuf[0] = 'E';

                           _itoa(nRead, &sendBuf[1], 10);

                           sendto(m_socket, sendBuf, nRead+0x12, 0,

                                    (SOCKADDR*)&addrTo, sizeof(SOCKADDR));

                           fclose(m_file);

                           m_progress.SetPos(m_nFileSize_s/0x100+1);

                           m_posting = false;

                           m_send = "发送进度:(100%)";

                           UpdateData(false);

                           MessageBox("发送完毕!");

                           m_progress.SetPos(0);

                           m_send = "发送进度:";

                           UpdateData(false);

                  }

                  else

                  {

                           //通信头,发送文件块

                           sendBuf[0] = 'F';

                           sendto(m_socket, sendBuf, 0x112, 0,

                                    (SOCKADDR*)&addrTo, sizeof(SOCKADDR));

                           m_progress.StepIt();

                           m_nSend++;

                           m_send.Format("发送进度:(%.1f%%)", (float)m_nSend/(m_nFileSize_s/0x100+1)*100);

                           UpdateData(false);

                  }

                  break;

        case 'H':

                  //对方申请发送文件

                  m_progress_r.SetRange(0, nFileSize/0x100+1);

                  m_nRecv = 0;

        case 'F':

                  //对方问询是否同意接收文件,本方回应同意"R"

                  sendto(m_socket, "R", 2, 0,

                                    (SOCKADDR*)lParam, sizeof(SOCKADDR));

                  m_progress_r.StepIt();

                  m_nRecv++;

                  m_recv.Format("接收进度:(%.1f%%)", (float)m_nRecv/(nFileSize/0x100+1)*100);

                  UpdateData(false);

                  break;

        case 'E':

                  //通信头,到了接收文件尾

                  m_progress_r.SetPos(nFileSize/0x100+1);

                  m_recv = "接收进度:(100%)";

                  UpdateData(false);

                  MessageBox("接收完毕!");

                  m_recv = "接收进度:";

                  m_progress_r.SetPos(0);

                  UpdateData(false);

                  break;

        case 'C':

                  //取消文件传输

                  sendto(m_socket, "D", 2, 0,

                                    (SOCKADDR*)lParam, sizeof(SOCKADDR));

                  break;

        }

}

6)在Dlg类中添加一个成员变量

int nFileSize;

Dlg.cpp中将其赋初值

int CUdpFileTransportDlg::nFileSize = 0;

7、设置进度条

Dlg.cpp初始化函数中添加

        m_progress.SetStep(1);

        m_progress_r.SetStep(1);

 

 

/********************************************************       FilePoster关键代码*E-mail:    andy.zhshg@163.com*日期:        2008.12.25**程序描述:*FilePoster是基于Win32平台的网络文件传输程序。开发平台为*Visual C++6.0。*程序采用服务器/客户机模式,服务器用于接收数据,客户机负责发送数据。利用windows多线程原理,集接收和发送功能于一体。*网络传输采用UDP原理,为解决UDP传输的不可靠性,用Windows*消息对收发的双方进行同步,即发送方先发送消息请求传送文件*同时发送要传文件的基本信息,收取方收到后回复发送发一个确*认消息,然后发送方依次发送被分成固定大小块(256字节)的文*件数据,收取方每收到一个数据块就写入自己的文件并回复发送*方一个接收完毕消息,以使得发送方发送下一个数据块。发送方*发送最后一个数据块时添加发送结束标记,接受方接收完毕后关*闭文件,至此发送过程结束。**问题阐述:*程序的缺陷在于只能用于具有固定IP的主机之间的文件传输。在*处于不同的内网中的主机无能为力。因为对于内网中的计算机其*IP是主机通过映射后分配来的所以如果不借助于服务器很难从外*网访问内网的计算机。不过对于处于同一局域网的计算机,本程*序还是能够完全应付的。*限于篇幅,与文件传输无关的代码省略,以"......"代替。*********************************************************//**********************************************************程序的初始化函数*********************************************************/BOOL CFilePosterApp::InitInstance(){    //加载套接字库     if(!AfxSocketInit())    {        AfxMessageBox("加载套接字库失败!");        return FALSE;    }    ......}/***********************************************************主窗口的初始化函数*struct RECVPARAM 用于传递线程数据**********************************************************/struct RECVPARAM{    HWND hWnd;    SOCKET sock;};BOOL CFilePosterDlg::OnInitDialog(){    ......    //设定进度条的步进值     m_progress.SetStep(1);    m_progress_r.SetStep(1);    //创建套接字     m_socket=socket(AF_INET,SOCK_DGRAM,0);    if(INVALID_SOCKET==m_socket)    {        MessageBox("套接字创建失败!");        return FALSE;    }    SOCKADDR_IN addrSock;    addrSock.sin_family=AF_INET;    addrSock.sin_port=htons(6800);    addrSock.sin_addr.S_un.S_addr=htonl(INADDR_ANY);    //绑定套接字     int retval;    retval=bind(m_socket, (SOCKADDR*)&addrSock,    sizeof(SOCKADDR));    if(SOCKET_ERROR==retval)    {        closesocket(m_socket);        MessageBox("绑定失败!");        return FALSE;    }    //产生一个用于接收数据的线程     struct RECVPARAM *pRecvParam=new RECVPARAM;    pRecvParam->sock=m_socket;    pRecvParam->hWnd=m_hWnd;    HANDLE hThread=CreateThread(NULL, 0, RecvProc,        (LPVOID)pRecvParam, 0, NULL);    CloseHandle(hThread);    ......}/***************************************************************接收线程的回调函数*发送的数据块结构解析:*类别 字节号     内容*H      1           通信头,申请发送*H      2~257       文件名*H      258~...     文件大小*D      1           通信头,拒绝接收*R      1           通信头,同意接收*F      1           通信头,发送文件块*F      2~17        保留*F      18~...      文件数据块*E      1           通信头,文件尾发送*E      2~17        块大小*E      18~...      文件数据块**************************************************************/DWORD WINAPI CFilePosterDlg::RecvProc(LPVOID lpParameter){    SOCKET sock=((RECVPARAM*)lpParameter)->sock;    HWND hWnd=((RECVPARAM*)lpParameter)->hWnd;    delete lpParameter;     SOCKADDR_IN addrFrom;    int len=sizeof(SOCKADDR);    char recvBuf[0x112];        //256+17字节的接受缓冲数组     char fileName[0x100];       //256字节的文件名存储区     int retval, i;    FILE* file = NULL;    while(TRUE)    {        //接受UDP数据         retval=recvfrom(sock, recvBuf, 0x112, 0,            (SOCKADDR*)&addrFrom, &len);                if(SOCKET_ERROR == retval)            break;        //收到消息头为'R',即对方同意让你继续发送数据         if (recvBuf[0] == 'R')        {            char wParam = 'R';            ::PostMessage(hWnd, WM_READY_TO_RECEIVE,                (WPARAM)&wParam, 0);        }        //收到消息头为'D',即对方拒绝让你继续发送数据         else if (recvBuf[0] == 'D')        {            char wParam = 'D';            ::PostMessage(hWnd, WM_READY_TO_RECEIVE,                (WPARAM)&wParam, 0);        }        //收到消息头为'H',即对方申请给你发送信息,并送来文件的信息         else if (recvBuf[0] == 'H')        {               //从收到的数据中提取文件名信息                     for (i = 1; i <= 0x100 && recvBuf[i] != '/0'; i++)                fileName[i-1] = recvBuf[i];            fileName[i-1] = '/0';            //从收到的数据中提取文件大小信息             CString recvMsg;            nFileSize = atoi(&recvBuf[0x101]);            recvMsg.Format("收到来自于(%s)的文件:%s/n文件大小:%i字节/n是否接收?",            inet_ntoa(addrFrom.sin_addr), fileName, nFileSize);            //用消息框提示用户有人要发送文件             if (IDOK == AfxMessageBox(recvMsg, MB_OKCANCEL))            {                //若用户同意接收,提供一个文件保存对话框用于设定保存的路径                 CFileDialog saveDlg(false, NULL, fileName);                if (IDOK == saveDlg.DoModal())                {                    //创建一个文件用于复制接收的文件数据                     if (!(file = fopen(saveDlg.GetPathName(), "wb")))                    {                        AfxMessageBox("创建本地文件失败!");                        continue;                    }                    char wParam = 'H';                    ::PostMessage(hWnd, WM_READY_TO_RECEIVE,                         (WPARAM)&wParam, (LPARAM)&addrFrom);                                    }                else                {                    char wParam = 'C';                    ::PostMessage(hWnd, WM_READY_TO_RECEIVE,                         (WPARAM)&wParam, (LPARAM)&addrFrom);                }            }            else    //用户拒绝接收             {                char wParam = 'C';                ::PostMessage(hWnd, WM_READY_TO_RECEIVE,                     (WPARAM)&wParam, (LPARAM)&addrFrom);            }        }        //收到的消息头为'F',即对方发来的是文件数据         else if (recvBuf[0] == 'F')        {            //将文件数据写入本地文件中             fwrite(&recvBuf[0x12], 1, 0x100, file);            char wParam = 'F';            ::PostMessage(hWnd, WM_READY_TO_RECEIVE,                 (WPARAM)&wParam, (LPARAM)&addrFrom);        }        //收到的消息头为'E',即对方发来最后一个数据块         else if (recvBuf[0] == 'E')        {            //获取数据块的大小             int bufSize = atoi(&recvBuf[1]);            //将数据块写入本地文件,并关闭文件             fwrite(&recvBuf[0x12], 1, bufSize, file);            fclose(file);            char wParam = 'E';            ::PostMessage(hWnd, WM_READY_TO_RECEIVE,                 (WPARAM)&wParam, (LPARAM)&addrFrom);        }        //收到未定义的数据头         else            AfxMessageBox("传送数据过程中出现错误!");    }    return (DWORD)NULL;}/**************************************************************按下发送键,发出文件信息的函数*************************************************************/void CFilePosterDlg::OnOK() {    if (m_posting)  //bool m_posting 表示程序是否正在发送文件     {        MessageBox("数据发送中,请稍候再试。");        return;    }    UpdateData();        if (m_filePath == "")    {        MessageBox("请输入要发送的文件路径!");        return;    }    if (m_IPAddr.IsBlank())    {        MessageBox("请添入接收者的IP地址。");        return;    }    WIN32_FIND_DATA FindFileData;    if (INVALID_HANDLE_VALUE == FindFirstFile(m_filePath, &FindFileData))    {        MessageBox("文件路径错误或文件不存在!/n请重新指定文件路径。");        return;    }    DWORD dwIP;    m_IPAddr.GetAddress(dwIP);    SOCKADDR_IN addrTo;    addrTo.sin_family=AF_INET;    addrTo.sin_port=htons(6800);    addrTo.sin_addr.S_un.S_addr=htonl(dwIP);    //构建文件信息数据块     char sendBuf[0x112];    int i;    //消息头     sendBuf[0] = 'H';    //文件名     for (i = 1; i <= 0x100 && FindFileData.cFileName[i-1] != '/0'; i++)        sendBuf[i] = FindFileData.cFileName[i-1];    sendBuf[i] = '/0';    //文件大小     _itoa(FindFileData.nFileSizeLow, &sendBuf[0x101], 10);    sendBuf[0x111] = '/0';    //发送数据块     sendto(m_socket, sendBuf, 0x112, 0,        (SOCKADDR*)&addrTo, sizeof(SOCKADDR));    //打开文件,等待读取     if (!(m_file = fopen(m_filePath, "rb")))    {        MessageBox("读取文件失败!");    }    m_nSend = 0;        //已发送的块数     m_nFileSize_s = FindFileData.nFileSizeLow;  //文件大小     m_progress.SetRange(0, m_nFileSize_s/0x100+1);//设置发送进度条     m_posting = true;   //标明发送正进行 }/*************************************************************消息响应函数*响应自定义消息WM_READY_TO_RECEIVE************************************************************/void CFilePosterDlg::OnReadyToRecv(WPARAM wParam,LPARAM lParam){    char sendBuf[0x112];    DWORD dwIP;    m_IPAddr.GetAddress(dwIP);    SOCKADDR_IN addrTo;    addrTo.sin_family=AF_INET;    addrTo.sin_port=htons(6800);    addrTo.sin_addr.S_un.S_addr=htonl(dwIP);    int nRead;    switch (*(char*)wParam)    {    //对方拒绝接收文件,关闭已打开的文件     case 'D':        MessageBox("对方拒绝接受你发送的文件!");        fclose(m_file);        m_posting = false;        break;    //对方同意接收文件     case 'R':        nRead = fread(&sendBuf[0x12], 1, 0x100, m_file);        //读取的文件小于256字节,则读到文件尾         if (nRead < 0x100)        {            sendBuf[0] = 'E';            _itoa(nRead, &sendBuf[1], 10);            sendto(m_socket, sendBuf, nRead+0x12, 0,                (SOCKADDR*)&addrTo, sizeof(SOCKADDR));            fclose(m_file);            m_progress.SetPos(m_nFileSize_s/0x100+1);            m_posting = false;            m_send = "发送进度:(100%)";            UpdateData(false);            MessageBox("发送完毕!");            m_progress.SetPos(0);            m_send = "发送进度:";            UpdateData(false);        }        //读到文件等于256字节,则文件还未读完         else        {            sendBuf[0] = 'F';            sendto(m_socket, sendBuf, 0x112, 0,                (SOCKADDR*)&addrTo, sizeof(SOCKADDR));            m_progress.StepIt();            m_nSend++;            m_send.Format("发送进度:(%.1f%%)",                (float)m_nSend/(m_nFileSize_s/0x100+1)*100);            UpdateData(false);        }        break;    //同意接收对方文件     case 'H':        m_progress_r.SetRange(0, nFileSize/0x100+1);        m_nRecv = 0;    case 'F':        sendto(m_socket, "R", 2, 0,                (SOCKADDR*)lParam, sizeof(SOCKADDR));        m_progress_r.StepIt();        m_nRecv++;        m_recv.Format("接收进度:(%.1f%%)", (float)m_nRecv/(nFileSize/0x100+1)*100);        UpdateData(false);        break;    //接受完毕,提示用户     case 'E':        m_progress_r.SetPos(nFileSize/0x100+1);        m_recv = "接收进度:(100%)";        UpdateData(false);        MessageBox("接收完毕!");        m_recv = "接收进度:";        m_progress_r.SetPos(0);        UpdateData(false);        break;    //拒绝接收,通知对方     case 'C':        sendto(m_socket, "D", 2, 0,                (SOCKADDR*)lParam, sizeof(SOCKADDR));        break;    }}