wstcl 2025-01-17 15:39 采纳率: 38.1%
浏览 18

c# 客户端访问java webcoket服务端发生异常

一个c# 写的客户端去访问java写的websocke服务端,然后客户端和服务端都有异常,客户端为“Connection”标头值“upgrade, keep-alive”无效。,服务端为java.io.EOFException,这是不是因为客户端为“Connection”标头值不符合java写的websocke服务端,服务端断开了客户断连接。为了证明到服务端还是客户端问题,作了以下测试
java编写安卓app客户端访问java写的websocke服务端无异常
java编写安卓app客户端访问nodejs写的websocket服务端无异常
C#编写安卓app客户端访问nodejs写的websocket服务端无异常
只有C#编写安卓app客户端访问java写的websocke服务端发生要述异常
之所以用java写的websocke服务端,是因为可以通过session.getBasicRemote()来获得某个客户端上下线
下面将java 和 C# 的代码贴出来
java

import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.OnError;
import javax.websocket.server.ServerEndpoint;

import com.sun.net.httpserver.Headers;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

import java.util.List;
import java.util.Map;
@ServerEndpoint("/testWebSocket")
public class WebSocketServer  {
 
    @OnOpen
    public void onOpen(Session session,EndpointConfig config) {
//        System.out.println("Connected ... " + session.getId());
        
        System.out.println( session.getBasicRemote()+"接入服务器 ");
    }
    
    
 
    @OnMessage
    public String onMessage(String message, Session session) {
        System.out.println("Received: " + message);
        return "Response: " + message;
    }
 
    @OnClose
    public void onClose(Session session) {
        System.out.println("Disconnected ... " + session.getId());
    }
    
    @OnError
    public void onError(Session session, Throwable throwable) {
        System.err.println("error: " + throwable.getMessage());
        throwable.printStackTrace();
    }
    
    
    
    
}

c#

using System;
using System.Net.WebSockets;
using System.Threading;
using System.Threading.Tasks;

class Program
{
    static void Main(string[] args)
    {

        Method1();

        Console.ReadKey();
    }

    public static async Task Method1()
    {

        try
        {
            var clientWebSocket = new ClientWebSocket();
            await clientWebSocket.ConnectAsync(new Uri("ws://localhost:1998/WebSocket/testWebSocket"), CancellationToken.None);
           

            Console.WriteLine("Connected!");

            // Send message to server
            var msg = "你好服务器!";
            var buffer = System.Text.Encoding.UTF8.GetBytes(msg);
            await clientWebSocket.SendAsync(new ArraySegment<byte>(buffer), WebSocketMessageType.Text, true, CancellationToken.None);

            // Receive message from server
            var receiveBuffer = new byte[1024 * 4];
            var receiveResult = await clientWebSocket.ReceiveAsync(new ArraySegment<byte>(receiveBuffer), CancellationToken.None);
            while (!receiveResult.CloseStatus.HasValue)
            {
                Console.WriteLine("Received message: " + System.Text.Encoding.UTF8.GetString(receiveBuffer, 0, receiveResult.Count));
                receiveResult = await clientWebSocket.ReceiveAsync(new ArraySegment<byte>(receiveBuffer), CancellationToken.None);
            }

            // Close connection
            await clientWebSocket.CloseAsync(receiveResult.CloseStatus.Value, receiveResult.CloseStatusDescription, CancellationToken.None);
            Console.WriteLine("Disconnected!");
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
        
    }


}

  • 写回答

2条回答 默认 最新

  • 关注

    以下回复参考:皆我百晓生券券喵儿等免费微信小程序作答:

    从你的描述和代码中,似乎出现问题的原因可能与WebSocket的握手过程有关。在WebSocket协议中,"Connection"标头字段是用于在握手过程中传递附加信息的。在客户端和服务器之间建立WebSocket连接时,如果服务器不接受客户端提供的"Connection"标头值,服务器可能会拒绝连接并返回错误。这就是为什么你的C#客户端访问Java WebSocket服务器时会报告这个错误的原因。服务器可能会期望客户端提供不同的"Connection"标头值。因此,客户端需要确认服务器期望的"Connection"标头值是什么,并在建立连接时提供正确的值。

    关于Java WebSocket服务器端的代码,看起来并没有对"Connection"标头进行特殊处理或检查。但是,如果服务器配置了对某些标头的特殊处理或检查,那么这可能是问题所在。你需要检查服务器的配置或联系服务器端的开发者了解服务器期望的WebSocket握手过程是什么样的。

    至于你的C#客户端代码,我看到你在连接WebSocket时并没有设置任何特定的HTTP头信息。因此,如果你需要设置特定的"Connection"标头值,你需要在连接WebSocket之前设置它。你可以使用HttpClient对象和HttpRequestMessage对象来设置这个值。但是你需要了解服务器的具体需求来确定需要设置什么样的值。示例代码如下:

    var httpHandler = new HttpClientHandler();
    var http = new HttpClient(httpHandler);
    var request = new HttpRequestMessage();
    request.Headers.Add("Connection", "your_value"); // 这里替换成服务器期望的值
    var clientWebSocket = new ClientWebSocket();
    await clientWebSocket.ConnectAsync(request, new Uri("ws://localhost:1998/WebSocket/testWebSocket"), CancellationToken.None);
    

    请注意替换上述代码中的"your_value"为服务器端实际的期望值。由于你提到的java端通过session.getBasicRemote()可以获得某个客户端的上下线状态,似乎不会针对“Connection”标头进行特殊处理或检查,所以问题可能出在客户端的握手过程上。你需要确认你的C#客户端是否正确地发送了所有必要的握手信息。

    评论

报告相同问题?

问题事件

  • 创建了问题 1月17日