TCP连接丢弃/或无法通过TCP接收数据

时间:2014-07-15 18:28:16

标签: c# tcp tcpclient tcplistener

我有一台客户端PC使用我编写的TCP_client程序通过TCP向我发送数据。基本上,我正在发送一条" Hello Message"到服务器。

class Program
{
    const int ourPort = 9090;
    static IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse("192.168.1.10"), 3000);
    static ASCIIEncoding encoder = new ASCIIEncoding();
    static System.Timers.Timer aTimer;
    static void Main(string[] args)
    {
        aTimer = new System.Timers.Timer(200);
        aTimer.Elapsed += OnTimedEvent;
        aTimer.Enabled = true;

        Console.Read();
    }

    private static void OnTimedEvent(Object source, ElapsedEventArgs e)
    {
        try
        {
            TcpClient client = new TcpClient();
            client.Connect(serverEndPoint);
            NetworkStream clientStream = client.GetStream();

            byte[] buffer = encoder.GetBytes("Hello Server!");

            clientStream.Write(buffer, 0, buffer.Length);
            clientStream.Flush();
        }
        catch (Exception ee)
        {
            Console.WriteLine(ee.ToString());
        }
    }

我正在使用我的PC来使用我编写的TCP_server程序接收数据。

class Server
{
    private static TcpListener tcpListener;
    static System.Timers.Timer aTimer;
    static int count = 0;
    public Server()
    {
        //
    }

    static void Main(string[] args)
    {
        tcpListener = new TcpListener(IPAddress.Any, 3000);
        tcpListener.Start();

        aTimer = new System.Timers.Timer(200);
        aTimer.Elapsed += OnTimedEvent;
        aTimer.Enabled = true;


        Console.Read();
    }

    private static void OnTimedEvent(Object source, ElapsedEventArgs e)
    {
        TcpClient client = tcpListener.AcceptTcpClient();
        Thread.Sleep(2);
        NetworkStream clientStream = client.GetStream();
        Thread.Sleep(2);

        byte[] message = new byte[4096];
        int bytesRead;

        bytesRead = 0;

        try
        {
            bytesRead = clientStream.Read(message, 0, 4096);
            client.Close();
        }
        catch (Exception ee)
        {
            Console.WriteLine("socket error");
            Console.WriteLine(ee.ToString());
            client.Close();
        }

        if (bytesRead == 0)
        {
            client.Close();
        }
        count++;

        ASCIIEncoding encoder = new ASCIIEncoding();
        Console.WriteLine(count + " " + encoder.GetString(message, 0, bytesRead));
    }

所有这一切,我所看到的问题是,偶尔我会遇到"套接字错误"在我的TCP_server程序的Catch()中。

错误:

System.IO.IOException: Unable to read data from the transport connection: An exi
sting 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 s
ize)
   --- End of inner exception stack trace ---
   at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 s
ize)
   at test_tcp_manager.Server.OnTimedEvent(Object source, ElapsedEventArgs e) in
 c:\Users\user\Documents\Visual Studio 2012\Projects\test_tcp_manager\test_tcp_ma
nager\Program.cs:line 52

错误发生在一秒钟或几秒钟内。我想知道为什么,我想知道如何解决这个问题。

U **来自用户输入的PDATE ** 来自用户的第一个代码修复用户反馈:

tcp_client代码现在看起来像这样:

 class Program
{
    const int ourPort = 9090;
    static IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse("172.22.1.22"), 3000);
    static ASCIIEncoding encoder = new ASCIIEncoding();
    static void Main(string[] args)
    {
        while (true)
        {
            try
            {
                using( TcpClient client = new TcpClient())
                {
                    client.Connect(serverEndPoint);
                    NetworkStream clientStream = client.GetStream();

                    byte[] buffer = encoder.GetBytes("Hello Server!");

                    clientStream.Write(buffer, 0, buffer.Length);

                    client.Close();
                }
            }
            catch (Exception ee)
            {
                Console.WriteLine(ee.ToString());
            }
        }
    }
}

和tcp_server代码现在看起来像这样:

class Server
{
    private static TcpListener tcpListener;
    static int count = 0;
    public Server()
    {
        //
    }

    static void Main(string[] args)
    {
        tcpListener = new TcpListener(IPAddress.Any, 3000);
        tcpListener.Start();
        while (true)
        {
            TcpClient client = tcpListener.AcceptTcpClient();
            NetworkStream clientStream = client.GetStream();

            byte[] message = new byte[4096];
            int bytesRead;

            bytesRead = 0;

            try
            {
                bytesRead = clientStream.Read(message, 0, 4096);
            }
            catch (Exception ee)
            {
                Console.WriteLine("Socket rror");
                Console.WriteLine(ee.ToString());
            }
            count++;

            ASCIIEncoding encoder = new ASCIIEncoding();
            Console.WriteLine(count + " " + encoder.GetString(message, 0, bytesRead));
        }
    }
}

1 个答案:

答案 0 :(得分:1)

  1. 发送邮件后不要忘记关闭客户端。连接将一直持续到GC决定关闭它。
  2. 刷新网络流没有任何作用。不要迷信所有东西,因为它似乎更安全。
  3. 您正在接受计时器。我以前从未见过这种错误。你为什么这样做?您应该在循环中接受所有连接的客户端,并独立地为它们提供服务。为什么每个计时器滴答服务器将服务器限制为一个客户端?
  4. 取消睡觉。每当你认为你需要睡觉时 - 想想更难。
  5. 您认为您将阅读"消息"在第一次阅读。 Read返回至少一个字节。它不保证其他任何东西。 TCP没有消息。确保您的代码可以按字节顺序处理接收传入数据。
  6. 对所有可支配资源使用using语句,并删除所有那些尴尬的Close调用。
  7. 很多问题。套接字编程很难。要非常小心。