File Transfer over Socket Between Windows Mobile Devices
在《利用WiFi在Windows Mobile上建立Ad-hoc网络》一文中,讲述了利用WiFi在Windows Mobile上建立Ad-hoc网络的方法。因为Ad-hoc网络建立了点对点的无线链接,可以不用接入点就能够实现设备之间的互联,因此具有方便、灵活、可配置的特点。在《IM over Socket Between Windows Mobile Devices》一文中,讲述了建立点对点的WiFi无线链接后,Windows Mobile设备之间利用Socket来实现消息的实时发送与接收。这篇文章将介绍后续内容,即建立点对点的WiFi无线链接后,Windows Mobile设备之间利用Socket来实现文件传输。
1. 应用程序分为Server端和Client端,由于是做Demo程序,这里只是实现了简单的文件传输功能,并没有涉及深入,如断点续传之类的。在Server和Client建立连接以后,在Server端将用户选择的文件传输给Client端,然后就结束传输。
2. 开发环境为Visual Studio 2008 + Windows Mobile 2003 for Pocket PC SDK + Windows Mobile 6 Pro SDK,使用MFC来开发。
3. 新建项目的时候,在Advanced Features选项中,选中Windows sockets,以添加对Socket的支持(在《IM over Socket Between Windows Mobile Devices》一文中已经给出了图示)。
4. 在Server端和Client端的头文件中,加入文件信息的结构体:
typedef struct _SOCKET_STREAM_FILE_INFO { TCHAR szFileTitle[128]; //文件的标题名 DWORD dwFileAttributes; //文件的属性 FILETIME ftCreationTime; //文件的创建时间 FILETIME ftLastAccessTime; //文件的最后访问时间 FILETIME ftLastWriteTime; //文件的最后修改时间 DWORD nFileSizeHigh; //文件大小的高位双字 DWORD nFileSizeLow; //文件大小的低位双字 DWORD dwReserved0; //保留 DWORD dwReserved1; //保留 } SOCKET_STREAM_FILE_INFO, * PSOCKET_STREAM_FILE_INFO;
5. 在Server端添加按钮,在按钮的点击事件中,让用户选择本地文件,然后发送给Client端。在Client端添加按钮和Server端的IP地址输入框,在输入Server端的IP地址后,点击按钮,然后接收Server端发送过来的文件。
6. 这里使用的是CSocket来进行通信,更多信息可以参考MSDN:CSocket Class。CSocket里面的方法是阻塞式的,所以在发送、接收较大文件的时候,给用户的感觉就是死机一样,为了能够给用户进行提示,我们还是加入发送文件的进度条为好。那么如何来实现文件传输进度条呢?因为我们是分段进行传输的,即每次发送1024个Bytes,而文件的总大小是可知的。所以,在发送或者接收文件内容的时候,我们可以进行计数,从而知道完成的百分比,把相关信息显示在进度条上。(注意:这里只用到了文件大小的地位双字)
7. 关键代码如下:
Server端:
UINT dwRead=0; while(dwRead<StreamFileInfo.nFileSizeLow) { byte* data = new byte[1024]; UINT dw=myFile.Read(data, 1024); sockRecv.Send(data, dw); dwRead+=dw; //set progress bar myCtrl.SetPos(dwRead*100/StreamFileInfo.nFileSizeLow); } myFile.Close();
Client端:
UINT dwRead = 0; while(dwRead<StreamFileInfo.nFileSizeLow) { byte* data = new byte[1024]; memset(data,0,1024); UINT dw=sockClient.Receive(data, 1024); destFile.Write(data, dw); dwRead+=dw; //set progress bar myCtrl.SetPos(dwRead*100/StreamFileInfo.nFileSizeLow); }
8. 为了更好地提示用户,在传输文件/接收文件过程中,我们可以加入“系统忙”的提示,即用以下代码对来实现:
//set wait sursor SetCursor(LoadCursor(NULL, IDC_WAIT)); //close wait sursor SetCursor(NULL);
9. 代码测试。按照《利用WiFi在Windows Mobile上建立Ad-hoc网络》的方法,利用WiFi在Windows Mobile上建立Ad-hoc网络。在Windows Mobile 2003se for Pocket PC设备上运行Client端程序,在Windows Mobile 6 Professional设备上运行Server端程序,如下图所示:
图1: Client端程序界面
图2: Server端程序打开文件界面
图3: Server端文件发送完毕界面
图4: Client端文件接收完毕界面
图5: Client端接收文件位置
参考链接:
1. 利用WiFi在Windows Mobile上建立Ad-hoc网络
2. IM over Socket Between Windows Mobile Devices
源代码工程下载:TCPFile.rar (Visual Studio 2008 + Windows Mobile 2003 for Pocket PC SDK + Windows Mobile 6 Pro SDK)