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

Java代码连接@ServerEndpoint标注的WebSocket服务遇UnknownHostException求助

解决Java代码连接WebSocket服务器的问题

嘿,我来帮你理清楚问题出在哪,以及怎么解决~

首先你犯了两个关键错误:

  • 用错了类:Socket是用来建立基础TCP连接的,完全不支持WebSocket的握手协议和帧格式,WebSocket是基于HTTP升级的协议,得用专门的WebSocket客户端来连接。
  • 地址格式错误:Socket的第一个参数只能是主机名(比如localhost)或者IP地址,不能带路径(/socketserver/wsock),所以你写的localhost/socketserver/wsock会被当作一个不存在的主机名,自然报UnknownHostException。

正确的解决思路

Java里连接WebSocket有几种常见方式,我给你推荐两种最常用的:

方式一:用Java官方的JSR 356 WebSocket API

JSR 356是Java的标准WebSocket API,你可以用它来编写客户端。首先需要引入依赖,如果是Maven项目,添加:

<dependency>
    <groupId>javax.websocket</groupId>
    <artifactId>javax.websocket-api</artifactId>
    <version>1.1</version>
    <scope>provided</scope>
</dependency>
<!-- 独立客户端需要的Tyrus实现依赖 -->
<dependency>
    <groupId>org.glassfish.tyrus</groupId>
    <artifactId>tyrus-client</artifactId>
    <version>1.17</version>
</dependency>
<dependency>
    <groupId>org.glassfish.tyrus</groupId>
    <artifactId>tyrus-container-grizzly-client</artifactId>
    <version>1.17</version>
</dependency>

然后编写客户端端点类,处理连接、消息、关闭事件:

import javax.websocket.ClientEndpoint;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;

@ClientEndpoint
public class MyWebSocketClient {

    @OnOpen
    public void onOpen(Session session) {
        System.out.println("WebSocket连接已打开");
        // 连接成功后可以发送消息给服务器
        try {
            session.getBasicRemote().sendText("Hello from Java client!");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @OnMessage
    public void onMessage(String message) {
        System.out.println("收到服务器消息:" + message);
    }

    @OnClose
    public void onClose() {
        System.out.println("WebSocket连接已关闭");
    }
}

最后编写连接代码:

import javax.websocket.ContainerProvider;
import javax.websocket.WebSocketContainer;
import java.net.URI;

public class Main {
    public static void main(String[] args) {
        // 这里用完整的WebSocket地址,和你JS里的格式完全一致
        String wsUrl = "ws://localhost:8084/socketserver/wsock";
        WebSocketContainer container = ContainerProvider.getWebSocketContainer();
        try {
            container.connectToServer(MyWebSocketClient.class, URI.create(wsUrl));
            // 保持客户端进程运行,避免连接后直接退出
            Thread.sleep(Long.MAX_VALUE);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

方式二:用第三方库(比如OkHttp,更轻量)

如果你觉得JSR 356有点重,可以用OkHttp的WebSocket客户端,它更简洁。首先添加Maven依赖:

<dependency>
    <groupId>com.squareup.okhttp3</groupId>
    <artifactId>okhttp</artifactId>
    <version>4.10.0</version>
</dependency>

然后编写连接代码:

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.WebSocket;
import okhttp3.WebSocketListener;
import okio.ByteString;

public class OkHttpWebSocketClient {
    public static void main(String[] args) {
        String wsUrl = "ws://localhost:8084/socketserver/wsock";
        OkHttpClient client = new OkHttpClient();

        Request request = new Request.Builder().url(wsUrl).build();
        WebSocketListener listener = new WebSocketListener() {
            @Override
            public void onOpen(WebSocket webSocket, okhttp3.Response response) {
                System.out.println("WebSocket连接已打开");
                webSocket.send("Hello from OkHttp client!");
            }

            @Override
            public void onMessage(WebSocket webSocket, String text) {
                System.out.println("收到服务器消息:" + text);
            }

            @Override
            public void onMessage(WebSocket webSocket, ByteString bytes) {
                System.out.println("收到二进制消息:" + bytes.hex());
            }

            @Override
            public void onClosing(WebSocket webSocket, int code, String reason) {
                webSocket.close(1000, null);
                System.out.println("WebSocket正在关闭:" + reason);
            }

            @Override
            public void onClosed(WebSocket webSocket, int code, String reason) {
                System.out.println("WebSocket已关闭:" + reason);
            }

            @Override
            public void onFailure(WebSocket webSocket, Throwable t, okhttp3.Response response) {
                t.printStackTrace();
            }
        };

        WebSocket webSocket = client.newWebSocket(request, listener);
        // 保持客户端进程运行
        client.dispatcher().executorService().awaitTermination(Long.MAX_VALUE, java.util.concurrent.TimeUnit.NANOSECONDS);
    }
}

关键注意点

  • 确保你的WebSocket服务器正常运行,端口8084开放,路径/socketserver/wsock的映射和JS访问时完全一致。
  • 如果是远程服务器测试,把localhost换成实际IP(比如你之前用的192.9.200.73)即可。
  • 依赖版本可以根据自己的项目需求调整,保证版本兼容即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:24:59