首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > Eclipse开发 >

java socket 图片传输解决方法

2012-12-15 
java socket 图片传输如题所示,我想用java,通过socket实现客服端像服务器端循环的传输图片,在服务器端能够

java socket 图片传输
如题所示,我想用java,通过socket实现客服端像服务器端循环的传输图片,在服务器端能够正确的获取每张图片。现在我已经实现了单张传输,也可以正常的在服务器端接收了。但是当我在客服端循环不停的发送时,服务器端就没法正常的接收,图片一直只有一张,在不停的增大,相当于全部累计在一个图片文件上面去了。该怎么正确的把客服端发送的图片分割开来,存为不同的图片呢?
我在网上查了很多相关的资料,说自定义分隔符,在服务器端根据分隔符区分;或者先发送个图片的大小再发送图片文件,在服务器端通过大小来区分。但是我在服务器端怎么才能区分获取得到的就是分隔符,或者是图片的大小呢?客服端在不停的循环发送,服务器端在循环的接收。
希望做过这方面编程的人提供帮助。最好能够有代码,因为原理我已经查了很多很多了。谢谢!
[最优解释]

package net;

import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class DataSocketServer {
    final public static int DEFAULT_PORT = 4848;
    final public static String FILE_DIR = "D:/";

    public static void main(String[] args) {
        ServerSocket server = null;
        try {
            server = new ServerSocket(DEFAULT_PORT);

            while (true) {
                new Thread(new RequestProcessorTask(server.accept())).start();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    static class RequestProcessorTask implements Runnable {
        private Socket socket = null;

        public RequestProcessorTask(Socket socket) {
            this.socket = socket;
        }

        public void run() {
            try {
                boolean isEnd = false;

                BufferedInputStream in = new BufferedInputStream(socket.getInputStream());

                while (!isEnd) {
                    int d = -1;
                    StringBuilder header = new StringBuilder();

                    while ((d = in.read()) != '\r') {
                        if (d == -1) {
                            isEnd = true;


                            break;
                        }
                        header.append((char) d);
                    }
                    if (!isEnd) {
                        String[] parms = header.toString().split(";");

                        FileOutputStream out = new FileOutputStream(FILE_DIR + parms[0]);
                        long size = Long.parseLong(parms[1]);

                        while (size > 0 && (d = in.read()) != -1) {
                            out.write(d);
                            size--;
                        }

                        out.flush();
                        out.close();
                    }
                }
                in.close();
            } catch (IOException e) {
                throw new RuntimeException("获取客户端输入流失败", e);
            }
        }
    }
}



这几天有点忙 没办法写的好一些 大概就是这么个意思 你可以配合不同的装饰器去做这个事情
[其他解释]
out.write(buf.length);
服务器端读完这个长度,就是下一张图片了。
[其他解释]
我有三个问题:
1.你能不能成功传送一张图片
2.你成功传送一张图片以后,有没有告知客户端/服务器端
3.你是如何处理socket传送出错和Socket Stream Buffer同步问题的

===============================================================
如果你找到这三个问题答案,你的问题就解决了...
[其他解释]
1.发送一个准备传输信息,至少包含 文件名。 对方确认后, c/s 双方准备传输。


2.开始传输:
c->s发送数据,循环; 
c->s发送传输完成命令,s确认,s端 close FileOutputStream。

3.循环整个流程。

应该定义一些命令号,防止传输中出现问题。比如:
1001:准备传输(包含文件名)
1002:确认准备传输
1003:文件块信息
1004:确认文件块信息
... ...
[其他解释]
自己定义个格式,比如说前2个byte为文件名长度,然后读取对应长度作为文件名,接下来定义8个byte的为文件内容的值,然后读取对应长度的byte写入文件。那接下来就是洗一张图片了
[其他解释]
OutputStream os = socket.getOutputStream();  //得到输出流
InputStream is = socket.getInputStream();   //得到输入流
DataOutputStream dos = new DataOutputStream(os);  
DataInputStream dis = new DataInputStream(is);
客户端先用DataOutputStream发送图片长度。再用OutputStream发送图片字节。
服务端,先用DataInputStream接收图片长度,再用InputStream接收图片字节

[其他解释]
将图片转换成base64编码方式,然后将base64通过socket以字符串方式发出去。
[其他解释]
lz是如何发送数据的
[其他解释]

引用:
lz是如何发送数据的

socket = new Socket(ip,port);
out=socket.getOutputStream(); 
 byte [] buf=Bitmap2Bytes(ScreenBmp);//ScreenBmp是bmp的图片
out.write(buf.length);
out.write(buf, 0, buf.length);
代码就是这样的,只是我还添加了定时器,循环发送

[其他解释]
引用:
out.write(buf.length);
服务器端读完这个长度,就是下一张图片了。

buf.length在服务器端怎么获取?这是问题所在。
[其他解释]
wite和read是对应的

out.write(buf.length);// in.read();
out.write(buf, 0, buf.length); //in.read(buf, 0, buf.length);
[其他解释]
知道是对应的,但一个在客服端,一个在服务器端。服务器端怎么获取这个长度?我这个意思应该还是表达清楚了的。
老兄,你懂的话,就贴下代码。
[其他解释]
我不懂啊,只不过帮你分析一下。
[其他解释]
引用:
我有三个问题:
1.你能不能成功传送一张图片
2.你成功传送一张图片以后,有没有告知客户端/服务器端
3.你是如何处理socket传送出错和Socket Stream Buffer同步问题的

===============================================================
如果你找到这三个问题答案,你的问题就解决了...

能成功传送一张图片(客服端只发送一次);
传送成功后,服务器端获取图片,然后输出成jpg文件,没有通知客服端;
第三个问题没有解决。
请指教
[其他解释]
客户端发送一个结束标记,服务端收到标记就算OK,要不就丢弃吧,研究下。
[其他解释]
引用:
客户端发送一个结束标记,服务端收到标记就算OK,要不就丢弃吧,研究下。

我在提出问题的时候已经说得很清楚了,我知道这个道理。我想问的是服务端怎么去获取这个标记。数据是循环发送的。

[其他解释]
for() {
out.write(buf.length);// in.read();
out.write(buf, 0, buf.length); //in.read(buf, 0, buf.length);
out.write(10000); //这个不可以吗?
}
[其他解释]
....没感觉你查了多少知识..
这里就是个比较麻烦的实现而已 你现在读取的时候我估计你是用数组 一段一段去读取 所以所谓的分隔符你不知道该如何判断 有个其他的建议
代码稍后放出
------其他解决方案--------------------


引用:
for() {
out.write(buf.length);// in.read();
out.write(buf, 0, buf.length); //in.read(buf, 0, buf.length);
out.write(10000); //这个不可以吗?
}


客户端读取的时候需要逐个字节进行比较 而且由于客户端缓存大小的不同有的时候还要在已经读取的全部内容中逐行查找 这样是不太建议的 在一开始你可以将长度写入 但是长度位一定要固定 
[其他解释]
比如在写入一个长度后 马上跟一个换行符 
[其他解释]
谢谢大家的解答。我就是在接收端处理出错。
这样说吧,我在发送端的代码是:
out.write(buf.length);
out.write(buf, 0, buf.length);
buf里面存的是我转化为byte的图片,每个大小其实都是30k左右。客服端只管循环发送。
那么,我在服务器端该怎么接收,以把每张图片都保存为正确的图片?会的请贴下代码。谢谢
[其他解释]
...写完了 有点BUG 在测
[其他解释]
高手呢,请指教。

[其他解释]
引用:
OutputStream os = socket.getOutputStream(); //得到输出流
InputStream is = socket.getInputStream(); //得到输入流
DataOutputStream dos = new DataOutputStream(os);  
DataInputStream dis = new DataInputStream(is……


也是一种方式 不过我没测 如果能够这样做的话 还不如用序列化呢
[其他解释]
引用:
引用:
引用:
OutputStream os = socket.getOutputStream(); //得到输出流
InputStream is = socket.getInputStream(); //得到输入流
DataOutputStream dos = new DataOutputStream(os);……


可以的 我现在有个应用我就是这么做的 
[其他解释]
引用:
引用:
OutputStream os = socket.getOutputStream(); //得到输出流
InputStream is = socket.getInputStream(); //得到输入流
DataOutputStream dos = new DataOutputStream(os);
DataInputStream dis ……


序列化好像不行 。我试过的。用的是ImageIcon ,它实现了Serializable 
[其他解释]
package net;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.Socket;

public class DataSocket {
    public static void main(String[] args) throws IOException {
        File img1 = new File("C:/Documents and Settings/dell/My Documents/My Pictures/002.jpg");
        File img2 = new File("C:/Documents and Settings/dell/My Documents/My Pictures/03342240.jpg");

        Socket socket = new Socket("127.0.0.1", 4848);
        String header1 = "a.jpg;" + img1.length();
        String header2 = "b.jpg;" + img2.length();

        BufferedOutputStream out = new BufferedOutputStream(socket.getOutputStream());



        FileInputStream in = new FileInputStream(img1);
        FileInputStream in2 = new FileInputStream(img2);
        byte[] buffer = new byte[8192];

        int readBytes = -1;

        out.write(header1.getBytes());
        out.write("\r".getBytes());
        out.flush();
        
        while ((readBytes = in.read(buffer)) != -1) {
            out.write(buffer, 0, readBytes);
        }
        out.flush();
        
        out.write(header2.getBytes());
        out.write("\r".getBytes());
        out.flush();
        
        while ((readBytes = in2.read(buffer)) != -1) {
            out.write(buffer, 0, readBytes);
        }
        out.flush();
        
        in.close();
        in2.close();
        out.flush();
        out.close();
    }
}



测试用的客户端
[其他解释]
刚看到回复。很感激。我认真看看代码。
[其他解释]
各位,我是新手,想请教一下。
我的socket的server和client是用wifi连接的,能把server上图片传输到client上吗?能一次性传递多张不?

[其他解释]
学习了.
[其他解释]
今天偶然看到这个帖子,其实楼主原理你知道,如果对io操作熟悉的话,你可以用字节流来实现。在图片之前传一个或两个字节信息表示图片长度,服务器端取出这个字节信息转化为长度信息,然后根据这个长度取多少个字节就行,这个长度就是read 的偏移量。这下取出的就是图片字节流,那么第一张图片就完成。第二张依次这么取就行。手机回复的。不好写代码,不过你应该明白。
[其他解释]
引用:
各位,我是新手,想请教一下。
我的socket的server和client是用wifi连接的,能把server上图片传输到client上吗?能一次性传递多张不?
肯定可以传的啊,也可以传多张,在接收端分割
[其他解释]
out.write(Len );
out.write(buf, 0, buf.length); 
----
Len = func (in.read ());
in.read(buf, 0, Len );
基本是这样,需要完善。

热点排行