转载请注明本文出自Xzhi的博客(http://blog.csdn.net/CSDN_zhi/article/details/71077050),请尊重他人的辛勤劳动成果,谢谢!

前言

这个解决方案是我和队友在《物联网》比赛的集训中得到的。在socket中Android客户端接收图片是相当的棘手(反正我当时就是这样觉得),接收文字还算简单。在刚开始接触socket接收图片的时候,出现一大堆意想不到的结果,要么图片显示不出来,要么图片显示不完整都有可能,下面我给出自己的解决方案,如果您有幸碰到了这个问题而且正在不知道怎么解决而发愁的时候,希望这篇文章能给您一些帮助。

开车

相信你们刚开始也会像我一样犯了这样一个错误用了下面这一段代码处理流的接收

while((len = inputStream.read(bs))!=-1)

这段代码并没有错,只是我们还不太了解socket通信的原理。
当你在socket使用这段代码,你将永远都接收不到数据,因为socket一旦通信是一直连接,所以永远得不到返回-1,除非对方断开连接。还有在socket通信中不能随便关闭流,否则将影响双方的通信,要在适当的时候关闭流才是最佳的做法。

核心代码

由于我写的是简单的接收和发送,没有其他的东西,所以我直接贴核心代码就行,当然我也会把源码链接放在下面给大家共享。

接收图片

Socket socket = new Socket("192.168.162.59", 9999);InputStream inputStream = socket.getInputStream();//begin 图片接收//第1步:接收服务端发过来的图片大小byte[] picLenBuff = new byte[200];int picLen = inputStream.read(picLenBuff);//将String 转换成 intString picLenString = new String(picLenBuff, 0, picLen);int getPicLen = Integer.valueOf(picLenString);//第2步:回馈。向服务端反馈客户端已经接收到图片的大小了,可以开始发图片了OutputStream outputStream = socket.getOutputStream();String string = "1";outputStream.write(string.getBytes());outputStream.flush();//第3步:开始接收图片int offset = 0;//定义偏移量byte[] bitmapBuff = new byte[getPicLen];//初始化图片缓存/**********************最主要部分***********************/while(offset < getPicLen){    int len = inputStream.read(bitmapBuff, offset, getPicLen-offset);    offset+=len;}/**********************最主要部分***********************///开始图片解码Bitmap bitmap = BitmapFactory.decodeByteArray(bitmapBuff, 0, offset);//用handler通知UI线程显示图片Message message = handler.obtainMessage(1, bitmap);handler.sendMessage(message);//end 

发送图片

Socket socket = new Socket("192.168.162.59", 9999);OutputStream outputStream = socket.getOutputStream();//初始化2M以内的图片缓存byte[] PicBuff = new byte[1024*1024*2];FileInputStream fileInputStream = new FileInputStream(Environment.getExternalStorageDirectory()+"/20.png");//得到图片大小int lenPic = fileInputStream.read(PicBuff);String lenString = String.valueOf(lenPic);//向服务端发送图片大小outputStream.write(lenString.getBytes());outputStream.flush();//定义回馈byte[] getRec = new byte[1];InputStream inputStream = socket.getInputStream();inputStream.read(getRec);String string = new String(getRec);//如果得到回馈是1,说明服务端已经接收完图片大小,可以开始发送图片了if(string.equals("1")){    outputStream.write(PicBuff, 0, lenPic);    outputStream.flush();}

以上通信格式都需要事先和PC端说好,否则通信失败。

这里只要讲解下接收图片这段代码要注意的地方

/**********************最主要部分***********************/while(offset < getPicLen){    int len = inputStream.read(bitmapBuff, offset, getPicLen-offset);    offset+=len;}/**********************最主要部分***********************/
  1. 如果PC服务端发送的图片比较大,Android客户端不可能一次性读完全部输入流,所以要在while(offset < getPicLen)中循环读取。
  2. read函数中的第三个参数要减去偏移量,否则会出现图片显示不完整或显示不出来等问题。
    源码点击下载
赞赏支持

如果您觉得我的文章对您有帮助的话,请随意打赏。您的支持将鼓励我继续创作!

更多相关文章

  1. Android中Activity切换时共享视图元素的切换动画(4.x兼容方案)
  2. Android(安卓)SystemUI源代码分析和修改
  3. Android(安卓)高仿微信头像截取 打造不一样的自定义控件
  4. Android篮球计分器App
  5. android 绘图--简单手写绘图后保存为图片(demo)
  6. Android(安卓)Studio目录结构浅析
  7. Android用代码完成颜色渐变处理
  8. 《Android第一行代码》书籍划重点记录
  9. Android(安卓)开发技术周报 Issue#287

随机推荐

  1. 【ERROR】MySQL 1030 Got error 28 from
  2. 在数据库设计中使用用户名作为主键是不是
  3. 高性能Mysql第三版(第六章查询性能优化)
  4. Java Web开发中使用Mysql数据库
  5. You can&#39;t specify target table &#3
  6. SQLite和MySQL数据库的差别与应用
  7. 用左连接查询大表真的很慢
  8. 如何在cakephp中找到最新的记录?
  9. 修改MySql服务名?
  10. MySQL学习笔记(十二)运算符和函数一