简体   繁体   中英

Simple socket server in C# unexpectedly closes connection when trying to write data to client

I'm trying to figure out why this C# code:

int port = 8080;
var localAddr = IPAddress.Parse("127.0.0.1");

var server = new TcpListener(localAddr, port);
server.Start();

Console.WriteLine("Waiting for a connection... ");
var client = server.AcceptTcpClient();

Console.WriteLine("Connected!");            // Writes to console when "open" button
                                            // is pushed in browser.

NetworkStream stream = client.GetStream();

while (client.Connected)                    // successfully loops twice.
{
    string message = DateTime.Now.ToString();
    byte[] msg = Encoding.ASCII.GetBytes(message);

    stream.Write(msg, 0, msg.Length);       // Exception is thrown here; data
                                            // is never received in browser.

    Console.WriteLine("Sent: {0}", message);
    Thread.Sleep(1000);
}

client.Close();

is throwing the following exception (referenced in code comment above):

An unhandled exception of type 'System.IO.IOException' occurred in System.dll

Additional information: Unable to write data to the transport connection: An established connection was aborted by the software in your host machine.

The code I'm using on the browser looks like this:

<!DOCTYPE html>

<html>
    <head>
        <title>Socket Test</title>
    </head>
    <body>

        <div>
            <input id=message size=50 />
            <button type="button" onclick="sendMessage();" >Send</button> <br />
            <button type="button" onclick="openSocket();" >Open</button>
            <button type="button" onclick="closeSocket();" >Close</button>
        </div>

        <div id="messages"></div>

        <script type="text/javascript">

            var webSocket;
            var messages = document.getElementById("messages");

            function openSocket(){

                if(webSocket !== undefined && webSocket.readyState !== WebSocket.CLOSED){
                   writeResponse("WebSocket is already opened.");
                    return;
                }

                webSocket = new WebSocket("ws://127.0.0.1:8080");

                webSocket.onopen = function(event){
                    writeResponse("Connection opened.");
                };

                webSocket.onmessage = function(event){
                    writeResponse(event.data);
                };

                webSocket.onclose = function(event){
                    writeResponse("Connection closed with event code " + event.code);
                };

                 webSocket.onerror = function(event){
                    writeResponse(event.data);
                };
            }

            function closeSocket(){
                webSocket.close();
            }

            function sendMessage(){
                webSocket.send(message.value);
            }

            function writeResponse(text){
                messages.innerHTML += "<br/>" + text;
            }

        </script>
    </body>
</html>

...which I know works perfectly, because I can change the line

webSocket = new WebSocket("ws://127.0.0.1:8080");

to

webSocket = new WebSocket("ws://echo.websocket.org");

and get a good connection and echo replies from http://websocket.org .

Note: Unlike the websocket.org test, the browser never reports that the connection has been opened with the C# server, even though the C# server believes it has established a successful connection.

You can't use a TCP socket to communicate with a WebSocket directly. WebSockets are built on top of HTTP, and the initial request is an HTTP request to do the handshake and upgrade from HTTP connection to WebSocket connection, so you will need to implement a small http server first to handle the HTTP connection upgrade request.

An upgrade header looks like this

    GET /chat HTTP/1.1
    Host: server.example.com
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
    Origin: http://example.com
    Sec-WebSocket-Protocol: chat, superchat
    Sec-WebSocket-Version: 13

so either you use an existing library or read the relevant parts of https://tools.ietf.org/html/rfc6455

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM