0

I used to run a c# server and html client but the handshake between them failed :

html client console error

"WebSocket connection to 'ws://localhost:100/' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED"

server console output whet i run the server :

     Setting up server...
     Server setup complete
     Client connected, waiting for request...
     Received Text: GET / HTTP/1.1
     Host: localhost:100
     Connection: Upgrade
     Pragma: no-cache
     Cache-Control: no-cache
     Upgrade: websocket
     Origin: http://localhost:63342
     Sec-WebSocket-Version: 13
     User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, 
     like Gecko) Chrome/67.0.3396.99 Safari/537.36
     Accept-Encoding: gzip, deflate, br
     Accept-Language: fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7
     Cookie: wab_portalurl_persistent=https%3A%2F%2Fgeo-tebourbi.maps.arcgis.com; 
     wab_cr_theme-config-Plugin=%5B%5D
     Sec-WebSocket-Key: DjATMra8JUjbbvoD5EAz0Q==
     Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits

Text is a get time request Time sent to client Received Text: Text is a get time request Time sent to client

server.cs

   using System;
   using System.Collections.Generic;
   using System.Net;
   using System.Net.Sockets;
   using System.Text; 
   namespace MultiServer
 {
    class Program
{
    private static readonly Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    private static readonly List<Socket> clientSockets = new List<Socket>();
    private const int BUFFER_SIZE = 2048;
    private const int PORT = 100;
    private static readonly byte[] buffer = new byte[BUFFER_SIZE];
  static void Main()
    {
        Console.Title = "Server";
        SetupServer();
        Console.ReadLine(); // When we press enter close everything
       CloseAllSockets();
    }

    private static void SetupServer()
    {
        Console.WriteLine("Setting up server...");
        serverSocket.Bind(new IPEndPoint(IPAddress.Any, PORT));
        serverSocket.Listen(100);
        serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), null);
        Console.WriteLine("Server setup complete");
    }

    /// <summary>
    /// Close all connected client (we do not need to shutdown the server socket as its connections
    /// are already closed with the clients).
    /// </summary>
    private static void CloseAllSockets()
    {
        foreach (Socket socket in clientSockets)
        {
            socket.Shutdown(SocketShutdown.Both);
            socket.Close();
        }

        serverSocket.Close();
    }

    private static void AcceptCallback(IAsyncResult AR)
    {
        Socket socket;

        try
        {
            socket = serverSocket.EndAccept(AR);
        }
        catch (ObjectDisposedException) // I cannot seem to avoid this (on exit when properly closing sockets)
        {
            return;
        }

        if ( socket != null)
        {
            clientSockets.Add(socket);

            socket.BeginReceive(buffer, 0, BUFFER_SIZE, SocketFlags.None, ReceiveCallback, socket);
            Console.WriteLine("Client connected, waiting for request...");
            serverSocket.BeginAccept(AcceptCallback, null);

        }


    }

    private static void ReceiveCallback(IAsyncResult AR)
    {
        Socket current = (Socket)AR.AsyncState;
        int received;

        try
        {
            received = current.EndReceive(AR);
        }
        catch (SocketException)
        {
            Console.WriteLine("Client forcefully disconnected");
            // Don't shutdown because the socket may be disposed and its disconnected anyway.
            current.Close(); 
            clientSockets.Remove(current);
            return;
        }

        byte[] recBuf = new byte[received];
        Array.Copy(buffer, recBuf, received);
        string text = Encoding.ASCII.GetString(recBuf);
        Console.WriteLine("Received Text: " + text);

       // if (text.ToLower() == "get time") // Client requested time

            Console.WriteLine("Text is a get time request");
            byte[] data = Encoding.ASCII.GetBytes(DateTime.Now.ToLongTimeString());
            current.Send(data);
            Console.WriteLine("Time sent to client");

        if (text.ToLower() == "exit") // Client wants to exit gracefully
        {
            // Always Shutdown before closing
            current.Shutdown(SocketShutdown.Both);
            current.Close();
            clientSockets.Remove(current);
            Console.WriteLine("Client disconnected");
            return;
        }


       current.BeginReceive(buffer, 0, BUFFER_SIZE, SocketFlags.None, ReceiveCallback, current); 
    }
}

}

client.html

 <html>
  <head>

<script type = "text/javascript">
    function WebSocketTest() {

        if ("WebSocket" in window) {
            alert("WebSocket is supported by your Browser!");

            // Let us open a web socket
            var ws = new WebSocket("ws://localhost:100");

            ws.onopen = function() {

                // Web Socket is connected, send data using send()
                ws.send("get time");
                alert("Message is sent...");
            };

           ws.onmessage = function (evt) {
                var received_msg = evt.data;
                alert("Message is received...");
            };

           ws.onclose = function() {

                // websocket is closed.
                alert("Connection is closed...");
            };
        } else {

            // The browser doesn't support WebSocket
            alert("WebSocket NOT supported by your Browser!");
        }
    }
</script>

   </head>

      <body>
      <div id = "sse">
      <a href = "javascript:WebSocketTest()">Run WebSocket</a>
      </div>

      </body>
     </html>

Is there any problem with my code concerning the handshake step ? Thanks

1 Answers1

1

You are using WebSockets on the client side and plain sockets on server side. But, WebSockets are not the same as plain sockets and to communicate with a WebSockets client the server needs to speak the WebSockets application protocol.

See Writing a WebSocket server in C# how this could be done and see also Differences between TCP sockets and web sockets, one more time to understand why one cannot use a simple TCP server with a WebSockets client like you are trying to do.

Steffen Ullrich
  • 114,247
  • 10
  • 131
  • 172