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

如何配置Java Socket实现跨设备及跨网络通信?

Java网络编程:实现跨设备文件传输的修改方案

问题描述

我正在学习Java网络编程,实现文件和字符串传输,但目前仅能在localhost(本地主机)环境下运行。请问需要对现有代码做出哪些修改,才能实现与同一网络或其他网络中的设备通信?

我曾尝试将localhost替换为InetAddress.getLocalHost().getHostAddress()获取的IP地址,但未能成功,客户端持续报错:错误:java.net.ConnectException: 连接被拒绝

现有代码

Client.java

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.*;
import java.nio.file.Files;
import java.util.Arrays;
public class Client {
    private int fileSize;
    private String FileName;
    public void getFileInformation (File newFile) {
        fileSize = (int) newFile.length();
        FileName = newFile.getName();
    }
    public static void main (String [] args) {
        try {
            Client newClient = new Client ();
            Socket newSocket = new Socket("localhost",3333);
            DataInputStream newDataInput = new DataInputStream(newSocket.getInputStream());
            DataOutputStream newDataOutput = new DataOutputStream(newSocket.getOutputStream());  
            BufferedReader newReader = new BufferedReader(new InputStreamReader(System.in));
            System.out.println("Enter path of file: ");
            File newFile = new File(newReader.readLine());
            newClient.getFileInformation(newFile);
            newDataOutput.writeInt(newClient.fileSize);
            newDataOutput.writeUTF(newClient.FileName);
            byte [] fileData = Files.readAllBytes(newFile.toPath());
            System.out.println(Arrays.toString(fileData));
            newDataOutput.write(fileData);
            newSocket.close();
            newDataInput.close();
            newDataOutput.flush();
            newDataOutput.close();
            newReader.close();
        } catch (IOException ex) {
            System.out.println("Error: " + ex);
        }
    }
}

Server.java

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Server {
    private int fileSize;
    private String FileName;
    public static void main (String [] args) {
        try {
            Server newServer = new Server();
            ServerSocket newServerSocket = new ServerSocket(3333);  
            Socket newSocket = newServerSocket.accept();  
            DataInputStream newDataInput = new DataInputStream(newSocket.getInputStream());
            DataOutputStream newDataOutput = new DataOutputStream(newSocket.getOutputStream());  
            BufferedReader newReader = new BufferedReader(new InputStreamReader(System.in));
            newServer.fileSize = newDataInput.readInt();
            System.out.println(newServer.fileSize);
            newServer.FileName = newDataInput.readUTF();
            System.out.println(newServer.FileName);
            byte [] fileData = new byte [newServer.fileSize];
            newDataInput.readFully(fileData);
            FileOutputStream newOutputStream = new FileOutputStream(newServer.FileName);
            System.out.println(Arrays.toString(fileData));
            newOutputStream.write(fileData);
            newOutputStream.close();
            newSocket.close();
            newDataInput.close();
            newDataOutput.flush();
            newDataOutput.close();
            newReader.close();
        } catch (IOException ex) {
            System.out.println("Error: " + ex);
        }
    }
}

修改方案与问题排查

1. 服务器端:让ServerSocket监听所有网络接口

当前代码中ServerSocket默认只绑定localhost,无法接收其他设备的连接。修改为监听所有可用网络接口:

// 替换Server.java中的ServerSocket初始化代码
ServerSocket newServerSocket = new ServerSocket(3333, 50, InetAddress.getByName("0.0.0.0"));
  • 0.0.0.0表示服务器会监听所有网卡的请求,包括局域网IP和公网IP
  • 可选添加newServerSocket.setReuseAddress(true);,避免程序重启后端口被占用的问题

2. 客户端:指定服务器的实际IP地址

InetAddress.getLocalHost().getHostAddress()获取的是客户端自身的IP,必须替换为服务器设备的真实IP:

// 替换Client.java中的Socket初始化代码,把IP改成服务器的实际地址
Socket newSocket = new Socket("192.168.1.100", 3333);
  • 同一网络下:使用服务器的局域网IP(可通过ipconfig/ifconfig查看)
  • 跨网络下:使用服务器的公网IP,同时需要在路由器上配置端口映射(将3333端口转发到服务器的局域网IP)

3. 解决「连接被拒绝」的关键步骤

  • 先启动服务器,再启动客户端:服务器必须处于监听状态才能接收连接
  • 检查防火墙:服务器设备需开放3333端口,或临时关闭防火墙测试
  • 网络连通性:同一网络下确保客户端能ping通服务器的IP
  • 端口占用:确认3333端口没有被其他程序占用(可通过netstat -ano | findstr 3333(Windows)或lsof -i :3333(Linux/macOS)查看)

4. 代码优化建议(可选)

  • 调整资源关闭顺序:先关闭输出流,再关闭输入流,最后关闭Socket,避免资源泄漏
// 客户端正确的关闭顺序
newDataOutput.flush();
newDataOutput.close();
newDataInput.close();
newSocket.close();
newReader.close();
  • 大文件处理:当前Files.readAllBytes()会将整个文件加载到内存,大文件会导致内存溢出,建议改为分块读写:
// 客户端替换文件读取代码
try (InputStream in = Files.newInputStream(newFile.toPath())) {
    byte[] buffer = new byte[4096];
    int bytesRead;
    while ((bytesRead = in.read(buffer)) != -1) {
        newDataOutput.write(buffer, 0, bytesRead);
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 05:37:12