转载: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
一、对界面插件设置
1、IP控件,ID为IDC_IP_ADDR,变量名为:m_IPAddr。
2、待发送文件路径:ID为IDC_FILE_PATH,变量名为:m_filePath。
3、查找文件按钮,ID为IDC_FIND_FILE。
4、发送进度(即第一个)进程控制条,ID为IDC_PROGRESS_SEND,变量名为m_progress
5、接收进度(即第二个)进程控制条,ID为IDC_PROGRESS_RECV,变量名为:m_progress_r。
6、发送文件按钮,ID为:IDOK
7、退出按钮,ID为IDCANCEL
8、发送进度,ID为IDC_SEND,变量名为:m_send。
9、接收进度,ID为IDC_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要发文件给B,A首先发送的内容第一个字母为‘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)在Dlg的protected的//}}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; }}
- 转载:UDP文件传输的实现
- UDP文件传输的实现
- UDP文件传输的实现
- 一个UDP实现文件传输的设计--待续...
- 一个UDP实现文件传输的设计--待续...
- 实现UDP的可靠文件传输 练习
- java udp实现文件传输
- 基于UDP的文件传输
- 用UDP实现可靠文件传输
- 用UDP实现可靠文件传输
- 用UDP实现可靠文件传输
- 用UDP实现可靠文件传输
- java使用udp实现文件传输
- 利用TCP/UDP完成文件传输的设计和实现
- 基于UDP协议的文件传输
- tcp udp实现文件传输(java)
- java中UDP文件传输怎么实现?
- java中UDP文件传输怎么实现?
- awk的系统变量
- 在网页上画一条线段(HTML5 Canvas作图)
- centos恢复密码
- _beginthreadex
- Android通过ContentProvider传输文件
- 转载:UDP文件传输的实现
- 大批量数据查询优化--建立索引
- Android 解析XML之一 DOM
- 用RDLC报表(一)
- 数据库连接池
- Popup.js 弹出窗口
- 初学Android,图形图像之使用Bitmap和BitmapFactory(二十四)
- audio sox
- 在网页上画一个点(HTML5 Canvas作图)