TcpClient的 - 一个现有的连接被强行关闭远程主机 [英] TcpClient - An existing connection was forcibly closed by the remote host

查看:1560
本文介绍了TcpClient的 - 一个现有的连接被强行关闭远程主机的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

的信息

我一直在开发C#中的网页http服务器,并决定添加远程控制台功能。控制台可以从任何位置使用,并且使用的TcpListener(Web服务器)和TcpClient的(远程控制台)发送命令和功能通过。

I have been developing a web http server in c# and decided to add a remote console feature. The console can be used from any location and uses a TcpListener (web server) and a TcpClient (remote console) to send commands and functions through.

守则

这是我的服务器如下:

TcpListener consoleListener = new TcpListener(consolePort);
consoleListener.Start();
byte[] bytes = new Byte[256];
string data = null;
while (true)
{
    TcpClient client = consoleListener.AcceptTcpClient();
    data = null;
    byte[] msg = { 0 };
    int i;
    while ((i = client.GetStream().Read(bytes, 0, bytes.Length)) != 0)
    {
        data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
        if (data == "shutdown")
        {
            //Server shutdown logic.
        }
        //Other commands here...
        else
        {
            msg = Encoding.ASCII.GetBytes("Invalid command. Type 'help' or '?' to get a list of commands.");
        }
        client.GetStream().Write(msg, 0, msg.Length); //sends return message to console
    }
    client.Close(); //closes connection between client and server after EVERY command. Connection is reopened when a new command is sent.
}

请注意 - 服务器在一个单独的线程上运行的网络服务器和主都。控制台应用程序线程

Note - The server is run on a separate thread to both the webserver and main console application thread.

这是我的客户:

public static string Communicate(string text)
{
    try
    {
        TcpClient client = new TcpClient(ip, port); //initializes tcpclient (ip and port are correct)

        byte[] data = System.Text.Encoding.ASCII.GetBytes(text); //converts text to bytes for stream writing

        NetworkStream stream = client.GetStream();

        stream.Write(data, 0, data.Length);

        Console.WriteLine("Sent data: " + text);

        data = new Byte[256];

        string responseData = String.Empty; //initializes responsData string

        Int32 bytes = stream.Read(data, 0, data.Length);
        responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);
        client.Close();
        return responseData; //returns what server writes
    }
    catch (Exception ex)
    {
        return "An error occured\n" + ex.ToString();
    }
}



问题

我可以发送一个命令到服务器成功返回。然而,当我尝试发送另一个命令时,服务器会抛出以下错误:

I can send one command to the server with a successful return. However, when I try and send another command, the server throws the error below:

System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. ---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
   at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
   at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
   --- End of inner exception stack trace ---
   at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
   at ---.Server.ConsoleListener() in X:\Users\---\Documents\Visual Studio 2013\Projects\---\---\Program.cs:line x

我知道它不受防火墙或管理员海拔问题,我可以通过成功地发送一个命令。它是只在第二个命令发送它抛出这个错误

I know it is not firewall or administrator elevation problems as I can send one command through successfully. It is only on the second command sent that it throws this error.

下面是描述问题的屏幕截图:

Here is a screenshot describing the problem:

编辑:这样做了一些研究,我发现这个问题是最有可能的一个小错误在我的for循环的结果。但是,我不知道这个固定的任何方式,我不知道确切的问题:)。请帮我鉴定,所以我可以修复它​​。

By doing a little research, I found that the problem is most likely a result of a small error in my for loop. However, I do not know any way of fixing this as I do not know the exact problem :). Please help me identify it so I can fix it.

再次感谢

推荐答案

看来你的客户端关闭一个消息之后的连接。

It seems that your client closes the connection after one message.

responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);
client.Close();
return responseData; //returns what server writes

如果你想坚持的连接,你应该在客户端上一个循环类似于您在服务器上的人。如果你想每次都建立新的连接,你应该关闭流正常的服务,而不是有这样的循环。您仍然需要循环的情况下,该消息是再或者你需要指定命令最大长度。

If you want to persist the connection you should have a loop on the client similar to the one you have on the server. If you want to establish new connection every time you should close the stream gracefully on the serve and not have a loop like this. You will still need to loop in case the message is longer or you need to specify max length for the command.

这篇关于TcpClient的 - 一个现有的连接被强行关闭远程主机的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆