c++服务器与android通过socket网络编程进行文件传输解决方案

项目最新成品:http://blog.csdn.net/nuptboyzhb/article/details/8611179

@author:郑海波

注:该博文隶属于项目《基于C/S模式的android手机与PC机通信系统的开发》。

项目视频演示:http://v.youku.com/v_show/id_XNDgyNzcwNjY4.html

项目下载地址:http://blog.csdn.net/nuptboyzhb/article/details/8611179

编程思想:

C++作为服务器,android作为客户端,通过android设备的wifi使手机与电脑连接于同一个局域网内,然后建立基于TCP/IP协议的socket连接。然后进行文件传输。

Java与c++数据类型的匹配问题

《C++服务器与java进行socket通信案例》这篇博文讲述了有关int型等数据类型的转换。主要思路是:将所有的数据类型都转化为byte流,对byte流进行传输。在这里,c++服务器用char类型的数组,android用byte数组进行文件传输。

首先看一下服务器端的C++核心代码:

[文件传输的线程函数]

[c++ core codes]

DWORD WINAPI GetFileForAndroidThread(LPVOID lparam)

{

GetFileLparam *mData=(GetFileLparam*)lparam;

COMMAND cmd;

FILEINFO fi;

memset((char*)&fi, 0, sizeof(fi));

memset((char*)&cmd, 0, sizeof(cmd));

cmd.ID = mData->command.ID;

CFile file;

int nChunkCount = 0;

if(file.Open((char*)mData->command.lparam, CFile::modeRead|CFile::typeBinary))//打开要传输的文件

{

int FileLen = file.GetLength();//获得文件的大小

fi.FileLen = file.GetLength();

strcpy((char*)fi.FileName, file.GetFileName());

memcpy((char*)&cmd.lparam, (char*)&fi, sizeof(fi));

send(mData->client, (char*)&cmd, sizeof(cmd), 0);//将文件名和文件发小发送给客户端

CString str="";

str.Format("filename=%s,filelen=%d",fi.FileName,fi.FileLen);

mData->pServerDlg->m_listOutput.AddString(str);

nChunkCount = FileLen/CHUNK_SIZE_FOR_ANDROID;//计算总共要发送多少块数据

if(FileLen%CHUNK_SIZE_FOR_ANDROID != 0)

nChunkCount++;

char *date = new char[CHUNK_SIZE_FOR_ANDROID];//为每块数据申请内存空间

CString temp;

for(int i=0; i

{

temp.Format("send the count%d",i);

mData->pServerDlg->m_listOutput.AddString(temp);

int nLeft;//定义剩余的数据长度

if(i+1 == nChunkCount)

nLeft = FileLen-CHUNK_SIZE_FOR_ANDROID*(nChunkCount-1);

else

nLeft = CHUNK_SIZE_FOR_ANDROID;

int idx = 0;

file.Read(date, CHUNK_SIZE_FOR_ANDROID);

while(nLeft>0)//直到第i块数据发送完

{

int ret = send(mData->client, &date[idx], nLeft, 0);//发送数据

if(ret == SOCKET_ERROR)

mData->pServerDlg->m_listOutput.AddString("send data error,please try again! NUPT");

nLeft -= ret;

idx += ret;

}

}

file.Close();//关闭文件

delete[] date;//释放内存空间

}

return 0;//返回

}

其次,再看一下android客户端的java核心代码:

[由一个线程类,专门用于接收文件]

private class ThreadRecvAndWriteFile extends Thread {

String filename;

int FileLen;

FileOutputStream file;

// private byte []byteArrayData=new byte[CHUNK_SIZE];

public ThreadRecvAndWriteFile(String filename, int FileLen) {

this.filename = "/sdcard/" + filename;

this.FileLen = FileLen;

}

public void errorPro() {

byte errorDate[] = new byte[NetWorkErrorByte];

int errorLeft = NetWorkErrorByte;

int e_ret = 0;

int e_idx = 0;

while (errorLeft > 0) {

// int ret=recv(server,&date[idx],nLeft,0);

try {

e_ret = app.mGlobalSocket.getInputStream().read(errorDate,

e_idx, errorLeft);

} catch (Exception e) {

}

e_idx += e_ret;

errorLeft -= e_ret;

}

for (int i = 0; i < errorDate.length; i++) {

if (errorDate[i] != 0) {

try {

file.write(errorDate, i, NetWorkErrorByte - i);

file.flush();

FileLen -= (NetWorkErrorByte - i);

break;

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

}

public void run() {

isFileDownload = false;

isDownloading=true;

if (!app.isLink) {

return;

}

try {

NetDataTypeTransform mTransform = new NetDataTypeTransform();

File mFile = new File(filename);

file = new FileOutputStream(mFile);

errorPro();

int nChunkCount = FileLen / CHUNK_SIZE_FOR_ANDROID;

if (FileLen % CHUNK_SIZE_FOR_ANDROID != 0) {

nChunkCount++;

}

mHandler.sendEmptyMessage(-1);

for (int i = 0; i < nChunkCount; i++) {

mHandler.sendEmptyMessage(i);

byte date[] = new byte[CHUNK_SIZE_FOR_ANDROID];

int nLeft;

if (i + 1 == nChunkCount)// 最后一块

nLeft = FileLen - CHUNK_SIZE_FOR_ANDROID

* (nChunkCount - 1);

else

nLeft = CHUNK_SIZE_FOR_ANDROID;

int idx = 0;

int ret = 0;

while (nLeft > 0) {

// int ret=recv(server,&date[idx],nLeft,0);

ret = 0;

try {

ret = app.mGlobalSocket.getInputStream().read(date,

idx, nLeft);

} catch (Exception e) {

mHandler.sendEmptyMessage(-7);

}

idx += ret;

nLeft -= ret;

}

file.write(date, 0, idx);

file.flush();

Log.d("WriteFiles", "have recv count" + i);

}

file.close();

File checkFile = new File(filename);

if (checkFile.length() < FileLen) {

isFileDownload = false;

mHandler.sendEmptyMessage(0);

return;

} else {

isFileDownload = true;

}

isDownloading=false;

mHandler.sendEmptyMessage(MaxProgress);

// Toast.makeText(app.getApplicationContext(),"文件以保存到"+filename,Toast.LENGTH_SHORT).show();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}解释:为什么会有public void errorPro()函数。之前的编程过程中,并没有这个函数。而且,在模拟器上测试的时候,没有出现任何的问题。然而,当android程序安装在手机上之后,我就发现:每次下载的文件都不能使用,打不开!但是文件的大小却和源文件相同。当时,我的推断是:肯定是在无线传输过程中出现了差错!要知道,对于一个可执行程序而言,即便有1bit出错,程序也不能正常运行。然而,事情并不是这样的!!既然服务器和客户端建立的是基于TCP/IP协议的连接,那么它们之间的传输应该是可靠的!于是,我便用二进制文件比较器,对下载的文件和源文件进行对比,发现了一个奇怪的现象:下载的文件的前684个字节竟然全为0,而后面的字节才和源文件一致,并且文件缺少源文件的684个字节。于是,我就编写了一个errorPro()函数,将前面的全0字节给忽略掉,而不影响文件的传输。最终,代码在模拟器上和手机上都运行的很好!而且下载很大的文件时,也没有出错!我现在还不知道为什么会有684字节的全0出现在文件头部,而在模拟器上测试时却没有。以后想清楚之后,在此补充完整。

附加:对于这个软件中的截图查看功能,也要用到下载模块。修改完这个bug之后,每次都能成功的查看电脑的桌面了。

[置顶]

MobCtrl万能遥控-手机控制电脑软件简介[官方]

MobCtrl万能遥控手机远程控制电脑软件详细介绍作者:郑海波zhb931706659@126.com官方网站:http://www.mobctrl.netMobCtrl用户QQ交流群:3213672592014-06-23最新更新~MobCt

Android与OpenCV2.4.4(2013最新)搭建图像处理框架

Android与OpenCV2.4.4(2013最新)搭建图像处理平台注意事项一.环境搭建详细可以参考官方提供的文档:官方介绍1.首先是Android开发环境搭建:操作系统:Windows

Android自定义对话框的实现

自定义对话框的思路就是编写对话框的布局文件xml,然后在对话框中显示不同的控件。以下以显示文本控件为例(ImageView等都可以显示)。1.布局文件con

android c++服务器端,c++服务器与android客户端进行文件传输功能的实现相关推荐

  1. Linux断开usb调试命令,Android关闭USB的ADB调试和文件传输功能(禁用USB)【转】

    通过设置系统属性(System Property)[persist.sys.usb.config]即可实现关闭或打开USB调试和文件传输功能,其中mtp表示文件传输,adb表示adb调试,none表示 ...

  2. Android关闭USB的ADB调试和文件传输功能(禁用USB)

    点击打开链接 通过设置系统属性(System Property)[persist.sys.usb.config]即可实现关闭或打开USB调试和文件传输功能,其中mtp表示文件传输,adb表示adb调试 ...

  3. 利用TCP协议完成服务器与客户端之间文件传输

    利用TCP文件传输协议模拟与服务器的文件上传.下载操作,以及进入各种目录和列举当前目录文件状态操作.ls为查看当前目录,cd+目录名进入该目录,cd -则返回上一级目录,dow加文件名则下载文件到本地 ...

  4. 服务器下传Android端,本地Tomcat服务器接收android端上传的数据

    8种机械键盘轴体对比 本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选? 大体描述 android端提交账号和密码,Tomcat服务器端会接收到,eclipse的控制台输出得到的账号和密码. T ...

  5. android用上传图片到服务器上,Android使用post方式上传图片到服务器的方法

    本文实例讲述了Android使用post方式上传图片到服务器的方法.分享给大家供大家参考,具体如下: /** * 上传文件到服务器类 * * @author tom */ public class U ...

  6. 服务器端提示信息,服务器监控提示客户端

    服务器监控提示客户端 内容精选 换一换 本节定义了VR云渲游平台上报云监控的监控指标的命名空间.监控指标列表和维度定义,用户可以通过云监控检索VR云渲游平台产生的监控指标和告警信息.SYS.CVR表1 ...

  7. 服务器与客户端的文件传输报告,网络文件传输设计报告.doc

    网络文件传输设计报告 合肥学院 计算机科学与技术系 课程设计报告 2011-2012学年第一学期 课程Java语言程序设计课程设计名称网络文件传输系统专业班级08网络工程(1)班姓名王阳光指导教师金莹 ...

  8. Socket异步服务器,可以监控客户端的状态,功能有,文字测试,服务端向客户端传输屏幕录像(UDP传输)、监控客户端屏幕(UDP传输),抖动用户窗体、发送文件给用户、扫描客户的C盘目录。

    用VS2015工具C#语言编写了一个简单的Socket异步服务器,可以监控客户端的状态,功能有,文字测试,服务端向客户端传输屏幕录像(UDP传输).监控客户端屏幕(UDP传输),抖动用户窗体.发送文件 ...

  9. python局域网大文件_[源码]Python简易http服务器(内网渗透大文件传输含下载命令)...

    Python简易http服务器源码 import SimpleHTTPServer import SocketServer import sys PORT = 80 if len(sys.argv) ...

最新文章

  1. 如何通过网站优化的方式提升网站转化率?
  2. php 字节序,Linux_Linux中网络字节序和主机字节序,主机字节序就是我们平常说的 - phpStudy...
  3. 云炬创业政策学习笔记20210104
  4. JavaOne 2012覆盖率
  5. B - Friends
  6. c语言转图形化,「分享」C语言如何编写图形界面
  7. 生成awr报告时报ORA-06502: PL/SQL: 数字或值错误 : 字符串缓冲区太小
  8. python培训班靠谱吗-学python去哪个培训机构好?靠谱的python培训机构推荐
  9. 2018蓝桥杯A组:分数(3种方法 循环累称 快速幂运算 移位运算)
  10. BI系统的应用组织思路与数据分析模式
  11. 锐捷交换机配置保存到计算机,锐捷交换机常用配置命令汇总
  12. 更改html默认浏览器,如何设置或默认浏览器更改为浏览器,火狐,IE
  13. 多 “维” 优化——前端高并发策略的更深层思考
  14. 车金融|金融产品规则引擎的前世今生(下篇)
  15. gtx1050ti安装win10和ubuntu16.04双系统
  16. PCB设计时如何选择合适的叠层方案
  17. 福大软工 · 第八次作业 课堂实战+后续部分
  18. Java虚拟机 - JVM是什么?
  19. 电池高压安全注意事项
  20. 深度学习+符号表征=强大的多任务通用表征,DeepMind新论文可能开启AI新时代

热门文章

  1. 软件测试学习 之 QA、QC与QM
  2. cubic 如何用matlab,求助高手解决cubic绘图问题
  3. 远心镜头与普通镜头拍摄工件孔径对比
  4. iOS APP版本自动更新
  5. 手撸JDK之ReentrantLock锁那点事
  6. .reg文件添加、修改、删除注册表的方法
  7. azul zing_微软和Azul将OpenJDK提升到Azure云中
  8. mac 安装typescript
  9. uniapp 消息提示框
  10. 计算机网络中传输速率 带宽 吞吐量三者的区别