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

时间:2015-12-09 14:04:55

标签: c# sockets

我正在建立客户端(html page& javascript)和服务器(C#console app)之间的连接。目标是建立聊天界面。

我对以下代码有两个问题:

  1. 当用户键入消息时,它只将第一个消息发送到服务器
  2. 当我向其他用户显示发送的消息时,会出现奇怪的字符,例如��n~Z� (�B�(@
  3. 我的代码如下:

    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());
    });
    

    编辑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);
    }
    

1 个答案:

答案 0 :(得分:1)

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

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

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