首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用datainput/-outputstream在java套接字上发送jpg图像的问题

使用datainput/-outputstream在java套接字上发送jpg图像的问题
EN

Stack Overflow用户
提问于 2014-10-15 02:04:52
回答 2查看 2.2K关注 0票数 0

我希望通过TCP套接字连接将JPG映像从客户端发送到服务器。我将文件转换为客户机中的字节数组,然后在发送数组长度后将其发送到服务器。服务器将数据从socketinputstream逐个字节读取到一个新的字节数组,然后写入jpg文件。但是,数据已损坏,无法查看此图像。下面是客户端和服务器的核心java代码。

客户端:

代码语言:javascript
复制
Socket s = new Socket("localhost", 666);
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
String imgPath = "C:/Users/huehuehue/Documents/Uni/D0036D/prick1.JPG";
File file = new File(imgPath);
byte[] b = new byte[(int) file.length()];
FileInputStream fis = new FileInputStream(file);
fis.read(b);
fis.close();
dos.writeInt((int) file.length());
dos.flush();
dos.write(b, 0, b.length);
dos.flush();

服务器:

代码语言:javascript
复制
ServerSocket serverSocket = new ServerSocket(666);
Socket connect = serverSocket.accept();
DataInputStream dis = new DataInputStream(connect.getInputStream());
File file = new File("C:/Users/huehuehue/Documents/Uni/D0036D/PLAYERprick.JPG");
FileOutputStream fos = new FileOutputStream(file);
int arrlen = dis.readInt();
byte[] b = new byte[arrlen];
int i = 0;
for(i = 0; i < arrlen; i++) {
    b[i] = dis.readByte();
    i++;
}
fos.write(b, 0 , b.length);

我不明白为什么这是行不通的,任何帮助或建议都是非常感谢的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-10-15 02:19:23

代码语言:javascript
复制
int arrlen = dis.readInt();
byte[] b = new byte[arrlen];
int i = 0;
for(i = 0; i < arrlen; i++) {
    b[i] = dis.readByte();
    i++;
}

您要增加两次i,因此忽略了一半的输入,并将不忽略的内容写入错误的插槽中。幸运的是,有一个更简单的方法,这也是更有效的:

代码语言:javascript
复制
int arrlen = dis.readInt();
byte[] b = new byte[arrlen];
dis.readFully(b);

NB fis.read(b);无效。您不能假设它填充了缓冲区。您也应该在这里使用DataInputStream.readFully()

票数 1
EN

Stack Overflow用户

发布于 2014-10-15 02:24:34

您需要匹配套接字的两端,并且客户端没有完全填充您的byte[];相反,您的客户端可以在读取它时发送每个字节。而且,由于Java提供了BufferedInputStream,所以您不必直接手动使用和调整byte[]缓冲区。相反,你可以做这样的事情,

代码语言:javascript
复制
Socket s = new Socket("localhost", 666);
String imgPath = "C:/Users/huehuehue/Documents/Uni/D0036D/prick1.JPG";
File file = new File(imgPath);
try (InputStream is = new BufferedInputStream(new FileInputStream(file));
        DataOutputStream dos = new DataOutputStream(s.getOutputStream());) {
    dos.writeLong(file.length()); // <-- remember to read a long on server.
    int val;
    while ((val = is.read()) != -1) {
        dos.write(val);
    }
    dos.flush();
}

另外,您的服务器可以使用类似的BufferedOutputStream来获得缓冲区的好处,例如

代码语言:javascript
复制
ServerSocket serverSocket = new ServerSocket(666);
File file = new File("C:/Users/huehuehue/Documents/Uni/D0036D/PLAYERprick.JPG");
try (Socket s = serverSocket.accept();
        DataInputStream dis = new DataInputStream(
                s.getInputStream());
        OutputStream fos = new BufferedOutputStream(
                new FileOutputStream(file));) {
    long arrlen = dis.readLong();
    for (long i = 0; i < arrlen; i++) {
        fos.write(dis.read());
    }
    fos.flush();
}

而不必手动管理它。注意上面提到的,使用BufferedInputStreamBufferedOutputStream作为优化来管理缓冲。您可以删除它们,直接从File流中读取和写入它们。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26373333

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档