|
写了一个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中修改的。 |
|