C#套接字服务器和HTML/javascript套接字客户端

本文关键字:套接字 javascript 客户端 服务器 HTML | 更新日期: 2023-09-27 18:26:16

我正在客户端(html页面和javascript)和服务器(C#控制台应用程序)之间建立连接。目标是拥有一个聊天界面。

我对下面的代码有两个问题:

  1. 当用户键入消息时,它只向服务器发送第一条消息
  2. 当我显示发送给其他用户的消息时,它带有奇怪的字符,如��n~Z� (�B�(@

我的代码如下:

public static ManualResetEvent allDone = new ManualResetEvent(false);
static void Main(string[] args)
{
    Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
    server.Bind(new IPEndPoint(IPAddress.Any, 8080));
    server.Listen(128);
    while (true)
    {
        allDone.Reset();
        Console.WriteLine("Waiting for a connection...");
        server.BeginAccept(new AsyncCallback(callback_BeginAccept), server);
        // Wait until a connection is made before continuing.
        allDone.WaitOne();
    }
}
private static void callback_BeginAccept(IAsyncResult result)
{
    allDone.Set();
    Socket listener = (Socket)result.AsyncState;
    Socket handler = listener.EndAccept(result);
    byte[] buffer = new byte[1024];
    var i = handler.Receive(buffer);
    string headers = (Encoding.UTF8.GetString(buffer)).Substring(0, i);
    Console.WriteLine("------------------------------------");
    Console.WriteLine("--------- CLIENT HEADERS  ----------");
    Console.WriteLine("------------------------------------");
    Console.WriteLine(headers);
    // Handles the handshake -> this is working
    handshake(handler, result, headers);
    listOfPeopleInChat.Add(handler);
    StateObject state = new StateObject();
    state.workSocket = handler;
    handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(callback_BeginReceive), state);
}
public static void callback_BeginReceive(IAsyncResult ar)
{
    StateObject state = (StateObject)ar.AsyncState;
    Socket handler = state.workSocket;
    // Read data from the client socket.
    int bytesRead = handler.EndReceive(ar);
    if (bytesRead > 0)
    {
        state.sb.Append(Encoding.UTF8.GetString(state.buffer, 0, bytesRead));
        string content = state.sb.ToString();
        Console.WriteLine("Read {0} bytes from socket. 'n Data : {1}", content.Length, content);
        foreach (Socket i in listOfPeopleInChat)
            sendMessage(content, i); // This works only for the first message typed in
    }
}

编辑1:我处理WebSockets请求的javascript代码:

var socket = new WebSocket("http://localhost:8080");
socket.onopen = function(){
    message('<p class="event">Socket Status: '+socket.readyState+' (open)');
}
socket.onmessage = function(msg){
    message('<p class="message">Received: '+msg.data);
}
socket.onclose = function(){
    message('<p class="event">Socket Status: '+socket.readyState+' (Closed)');
}
$(document).on('click', '#send', function()
{
    socket.send($('#msg').val());
});

EDIT 2:sendMessage()函数如下:

private static void sendMessage(String mess, Socket client) 
{
    byte[] rawData = Encoding.UTF8.GetBytes(mess);
    int frameCount  = 0;
    byte[] frame = new byte[10];
    frame[0] = (byte) 129;
    if(rawData.Length <= 125){
        frame[1] = (byte) rawData.Length;
        frameCount = 2;
    }
    else if (rawData.Length >= 126 && rawData.Length <= 65535)
    {
        frame[1] = (byte) 126;
        int len = rawData.Length;
        frame[2] = (byte)((len >> 8 ) & (byte)255);
        frame[3] = (byte)(len & (byte)255); 
        frameCount = 4;
    }else{
        frame[1] = (byte) 127;
        int len = rawData.Length;
        frame[2] = (byte)((len >> 56 ) & (byte)255);
        frame[3] = (byte)((len >> 48 ) & (byte)255);
        frame[4] = (byte)((len >> 40 ) & (byte)255);
        frame[5] = (byte)((len >> 32 ) & (byte)255);
        frame[6] = (byte)((len >> 24 ) & (byte)255);
        frame[7] = (byte)((len >> 16 ) & (byte)255);
        frame[8] = (byte)((len >> 8 ) & (byte)255);
        frame[9] = (byte)(len & (byte)255);
        frameCount = 10;
    }
    int bLength = frameCount + rawData.Length;
    byte[] reply = new byte[bLength];
    int bLim = 0;
    for(int i=0; i<frameCount;i++){
        reply[bLim] = frame[i];
        bLim++;
    }
    for(int i=0; i<rawData.Length;i++){
        reply[bLim] = rawData[i];
        bLim++;
    }
    client.Send(reply);
}

C#套接字服务器和HTML/javascript套接字客户端

在服务器代码中,每个连接只尝试接收一次数据。

同样基于您的代码,如果任何消息大于缓冲区大小,您将只得到部分消息。

在接收回调中,您需要再次调用BeginReceive,以便可以接收另一条消息(或消息的其余部分)。