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
相关产品推荐
相关产品推荐

