简体   繁体   English

尝试将数据写入客户端时,C#中的简单套接字服务器意外关闭连接

[英]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: 我试图弄清楚为什么此C#代码:

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 System.dll中发生了'System.IO.IOException'类型的未处理异常

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 . 并获得良好的连接并从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. 注意:与websocket.org测试不同,浏览器从不报告已与C#服务器打开连接,即使C#服务器认为已建立成功连接也是如此。

You can't use a TCP socket to communicate with a WebSocket directly. 您不能使用TCP套接字直接与WebSocket通信。 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. WebSockets建立在HTTP之上,并且初始请求是一个HTTP请求,用于进行握手并从HTTP连接升级到WebSocket连接,因此您将需要首先实现小型http服务器来处理HTTP连接升级请求。

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 因此,您可以使用现有的库或阅读https://tools.ietf.org/html/rfc6455的相关部分

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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