写了一个Android客户端和java socket服务端。客户端把SD卡里的一张图传给服务端,服务端也收到了,也保存为一张图。接下来用服务端把保存的这张jpg图文件再通过DataOutputStream DOS=new DataOutputStream(s.getOutputStream());发给客户端。但测试了很多遍,客户端并没有收到这张图片。在看了看服务端的代码,发现执行到DOS.write(data);时,即服务端把图片数据写到DOS时就执行不下去了,不知道什么原因,求指导,在线等! package newserver; import java.io.BufferedOutputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; public class Server02 { //定义一个线性表,用来装新建好的socket public static ArrayList<Socket> socketList = new ArrayList<Socket>(); //定义一个线性表,用来装新建好的文件名 public static ArrayList<String> fileList = new ArrayList<String>(); //文件名序号 public static int no=0; public static void main(String[] args) throws IOException { ServerSocket ss = new ServerSocket(40000); while(true){ Socket s = ss.accept(); socketList.add(s); new Thread(new ServerThread(s)).start(); } } } package newserver; import java.io.BufferedOutputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.net.Socket; public class ServerThread implements Runnable{ Socket s=null; public ServerThread(Socket socket){ this.s=socket; System.out.println("一条线程启动"); } public void run(){ DataInputStream dis =null; FileOutputStream fos=null; DataOutputStream dos=null; DataOutputStream DOS =null; //每读取一条来自客户端的信息,都新建一个文件,文件名加1 Server02.no++; //用来保存客户端发来的信息的文件夹名,并加入到顺序表里面去 String fileName="image"+Server02.no+".jpg"; Server02.fileList.add(fileName); File file = new File(fileName); try{ //连接客户端的socket,为读取客户端输入做准备 dis =new DataInputStream(s.getInputStream()); DOS = new DataOutputStream(s.getOutputStream()); ByteArrayOutputStream bytestream = new ByteArrayOutputStream(); byte[] inputByte = new byte[1024]; int length = 0; //接受客户端的输入,输入到inputByte里,再输入到bytestream里 while ((length = dis.read(inputByte, 0, inputByte.length)) > 0) { bytestream.write(inputByte, 0, length); } fos=new FileOutputStream(file); //将bytestream的内容输入到jpg文件里面 dos = new DataOutputStream(fos); dos.write(bytestream.toByteArray()); dos.flush(); System.out.println("可以浏览照片了"); System.out.println("开启dos"); //读取图片文件到FIS流 FileInputStream FIS = new FileInputStream(Server02.fileList.get(Server02.no-1)); int size = FIS.available(); System.out.println("size = "+size); byte[] data = new byte[size]; FIS.read(data); //将内容写到DOS里面,即传给客户端的DataInputStream,内容包括数组大小和图片数据 DOS.writeInt(size); DOS.write(data); System.out.println(data); DOS.flush(); DOS.close(); FIS.close(); dos.close(); dis.close(); }catch(IOException e){ } } android客户端代码: package com.example.phototest2; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.IOException; import java.net.Socket; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Bundle; import android.os.Environment; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.Button; import android.widget.ImageView; import android.widget.Toast; import android.view.View.OnClickListener; public class MainActivity extends Activity { private Bitmap bitmap,bmp; private ImageView imageView02; private Button button01,button02; private final String fileName=Environment.getExternalStorageDirectory().getPath()+"/myImage/20150408_113803.jpg"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); imageView02 = (ImageView)findViewById(R.id.image02); button01=(Button)findViewById(R.id.Button01); button02 = (Button)findViewById(R.id.Button02); button02.setOnClickListener(new OnClickListener(){ public void onClick(View arg0) { File file=new File(fileName); if(file.exists()){ bitmap=BitmapFactory.decodeFile(fileName); Toast.makeText(MainActivity.this, "图片存在", Toast.LENGTH_LONG).show(); } else{ Toast.makeText(MainActivity.this, "图片不存在", Toast.LENGTH_LONG).show(); } //imageView02.setImageBitmap(bitmap); new Thread(){ Socket socket=null; @Override public void run(){ try{ socket = new Socket("110.64.90.157",40000); DataOutputStream out = new DataOutputStream(socket.getOutputStream()); ByteArrayOutputStream baos = new ByteArrayOutputStream(); //读取图片到ByteArrayOutputStream bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos); byte[] bytes = baos.toByteArray(); out.write(bytes); out.flush(); //System.out.println("bytes--->"+bytes); out.close(); //原来out.close();位置 DataInputStream dataInput = new DataInputStream(socket.getInputStream()); int size = dataInput.readInt(); byte[] data = new byte[size]; int len = 0; while (len < size) { len += dataInput.read(data, len, size - len); } //ByteArrayOutputStream outPut = new ByteArrayOutputStream(); bmp = BitmapFactory.decodeByteArray(data, 0, data.length); //dataInput.close(); }catch(IOException e){ e.printStackTrace(); } finally { try { socket.close(); Log.v("wei", "socket关闭"); } catch (IOException e) { e.printStackTrace(); } } } }.start(); } }); button01.setOnClickListener(new OnClickListener(){ public void onClick(View sourse) { imageView02.setImageBitmap(bmp); } }); } } android布局有两个Button,Button01用于显示后来服务端发回来的照片.,Button02用于上传图片到服务端。 |
|
求助!!
|
|
45分 |
粗略一看,应该是bmp是在线程里赋值的原因造成的
button01.setOnClickListener(new OnClickListener(){ public void onClick(View sourse) { // 断点这里,看看bmp赋值是否正确 imageView02.setImageBitmap(bmp); } }); |
虽然在里面赋值,但我是等上传完照片,我才按Button1显示bmp的,我已经等了足够久的时间了,但还是没有东西。我测试了一下,发现客户端在DataInputStream dataInput = new DataInputStream(socket.getInputStream()); 这里停住了,不知道什么原因。 |
|
50分 |
我也弄个相似的程序,也写 不出来,但是跟楼主的不一样地方是貌似就是bmp的值不知道,DataInputStream dataInput = new DataInputStream(socket.getInputStream())我应该运行出来了,因为后面的size值就是我发送的大小,请问这该怎么办? |
我解决了我的问题了,我的原因是直接通过setimagebitmap方法来改变Imageview的图片是不可以的,应该通过handler来传递调用,但你程序貌似没有我出现的问题,我也是新手,所以好多还不懂,求大神们多指点!希望大神们给个QQ,让我可以多请教!谢谢 |
|
5分 |
请将图片转化为base64
|
问题已经解决了,前些时间因为比较忙,也忘记了结贴。
问题的原因是:客户端在向服务端传送数据后,在第76行(android程序)中把输出流关闭了。这时客户端与服务端相连的socket也关闭了。这就会导致后来在服务端程序中使用这个socket的服务端输出流向客户端传数据时,找不到这个socket了,所以传不过去了。 解决办法:在android程序第76行把out.close();改为socket.shutdownOutputStream();从而解决了关闭输出流就关闭了socket的问题。 抽空特意来结贴,希望我们互相学习,共同进步。 |
|
你所说的不能通过setimagebitmap方法来改变Imageview的图片,是因为你在其他线程里调用,修改UI必须在线程UI中修改的。 |