You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中使用Socket实现客户端向服务器发送图片的技术咨询

Java Socket实现客户端向服务器传输图片

我来帮你完善这个基于Socket的图片传输实现,你的服务器端代码里用了字符流来处理图片是不对的——图片是二进制数据,得用字节流来读写才行。下面是完整的可运行实现:

服务器端代码

服务器通过线程循环等待客户端连接,一旦连接建立就用字节流接收图片数据并保存到本地:

import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class ImageServer extends Thread {
    private boolean running = true;
    private ServerSocket serverSocket;
    private static final int PORT = 8888;
    private static final String SAVE_PATH = "received_image.jpg";

    public ImageServer() throws Exception {
        serverSocket = new ServerSocket(PORT);
        System.out.println("服务器启动,等待客户端连接...");
    }

    @Override
    public void run() {
        while (running) {
            try (Socket clientSocket = serverSocket.accept()) {
                System.out.println("客户端已连接:" + clientSocket.getInetAddress());

                // 读取客户端发送的图片数据(用字节流)
                try (InputStream inputStream = clientSocket.getInputStream();
                     FileOutputStream fileOutputStream = new FileOutputStream(SAVE_PATH)) {

                    byte[] buffer = new byte[1024 * 4]; // 4KB缓冲区
                    int bytesRead;
                    while ((bytesRead = inputStream.read(buffer)) != -1) {
                        fileOutputStream.write(buffer, 0, bytesRead);
                    }
                    System.out.println("图片接收完成,已保存到:" + SAVE_PATH);

                    // 给客户端发送接收确认
                    clientSocket.getOutputStream().write("图片接收成功".getBytes());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public void stopServer() {
        running = false;
        try {
            serverSocket.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws Exception {
        new ImageServer().start();
    }
}

客户端代码

客户端负责读取本地图片,并通过Socket将二进制数据发送给服务器:

import java.io.FileInputStream;
import java.io.OutputStream;
import java.net.Socket;

public class ImageClient {
    private static final String SERVER_IP = "localhost";
    private static final int SERVER_PORT = 8888;
    private static final String IMAGE_PATH = "test_image.jpg"; // 要发送的本地图片路径

    public static void main(String[] args) {
        try (Socket socket = new Socket(SERVER_IP, SERVER_PORT);
             FileInputStream fileInputStream = new FileInputStream(IMAGE_PATH);
             OutputStream outputStream = socket.getOutputStream()) {

            byte[] buffer = new byte[1024 * 4]; // 4KB缓冲区
            int bytesRead;
            while ((bytesRead = fileInputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
            socket.shutdownOutput(); // 告诉服务器数据已发送完毕

            // 接收服务器的确认消息
            byte[] responseBuffer = new byte[1024];
            int responseLen = socket.getInputStream().read(responseBuffer);
            System.out.println("服务器响应:" + new String(responseBuffer, 0, responseLen));

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

关键注意事项

  • 必须使用字节流处理图片这类二进制数据,绝对不能用BufferedReader、PrintWriter这类字符流——字符流会对数据做编码转换,直接破坏图片的二进制结构,导致接收的图片无法打开。
  • 使用缓冲区(比如4KB大小的byte数组)可以减少IO操作的次数,大幅提升传输效率,避免频繁读写带来的性能损耗。
  • 用try-with-resources语法可以自动关闭流和Socket资源,不需要手动调用close(),避免资源泄漏。
  • 客户端发送完数据后调用socket.shutdownOutput(),可以明确告诉服务器“数据已经全部发送完毕”,否则服务器的inputStream.read()会一直阻塞等待数据。
  • 可以扩展功能:比如传输前先发送图片的文件名和大小,服务器根据这些信息创建对应文件名的文件,或者校验接收的字节数是否完整。

内容的提问来源于stack exchange,提问作者Wouter Thys

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:04:38