TcpClient和TcpServer在服务器可用时自动连接

时间:2014-08-04 14:10:05

标签: c#

我正在创建一个TcpServer和TcpClient,一旦服务器可用,客户端将自动连接服务器(继续尝试)。而且我不想丢失数据,这意味着当客户端向服务器发送数据并突然服务器关闭时,它将再次重试,因此下面的MnitorMiniTcpClientOwn.SendData将继续尝试直到成功。

然而,由于SendData请求中的继续尝试循环,服务器将接收多个相同命令的生产中存在问题。我不擅长网络编程,任何人都可以发现代码中的缺陷吗?

客户端

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Threading;

namespace NewCMS.Repositories
{
    public class MonitorMiniTcpClientOwn : IDisposable
    {
        public string ServerIP = "127.0.0.1";
        public int Port = 9090;
        TcpClient tc = null;
        string dataFromClient = string.Empty;
        NetworkStream stream = null;
        Thread RunningThread = null;
        public bool IsRunning = false;
        public string _Name = string.Empty;

        public virtual string InitialText
        {
            get
            {
                return string.Empty;
            }
        }

        public virtual void Start(string name)
        {
            _Name = name;
            if (tc != null)
            {
                Stop();
            }

            ThreadStart ts = new ThreadStart(StartThread);
            RunningThread = new Thread(ts);
            RunningThread.Start();
        }

        public void StopWithoutAbort()
        {
            if (tc != null)
            {
                try
                {
                    tc.Close();
                }
                catch (Exception ex)
                {
                }
            }
            if (stream != null)
            {
                try
                {
                    stream.Close();
                }
                catch (Exception ex)
                {
                }
            }
        }

        public virtual void Stop()
        {
            try
            {
                IsRunning = false;
                StopWithoutAbort();
                if (RunningThread != null)
                {
                    try
                    {
                        RunningThread.Abort();
                    }
                    catch { }
                }
            }
            catch { }
        }

        protected void StartThread()
        {
            IsRunning = true;
            while (IsRunning)
            {
                try
                {
                    tc = new TcpClient();
                    tc.Connect(ServerIP, Port);

                    byte[] inStream = new byte[10025];

                    stream = tc.GetStream();
                    int read = 0;
                    while ((read = stream.Read(inStream, 0, inStream.Length)) > 0)
                    {
                        dataFromClient += System.Text.Encoding.ASCII.GetString(inStream, 0, read);

                        string[] strs = dataFromClient.Split('\n');
                        if (strs != null)
                        {
                            for (int i = 0; i < strs.Length - 1; i++)
                            {
                                ProcessCommand(tc, strs[i]);
                            }
                            if (dataFromClient.EndsWith("\n"))
                            {
                                ProcessCommand(tc, strs[strs.Length - 1]);
                                dataFromClient = string.Empty;
                            }
                            else
                                dataFromClient = strs[strs.Length - 1];
                        }
                    }
                }
                catch (Exception ex)
                {
                    StopWithoutAbort();
                    if (IsRunning == false)
                    {
                        break;
                    }
                    IsRunning = true;
                    Thread.Sleep(1000);
                }
            }
        }

        public virtual void ProcessCommand(TcpClient tc, string str)
        {
        }

        public Exception SendData(string text)
        {
            Exception result = null;
            int tryIndex = 0;
            int tryCount = 5;
            while (tryIndex < tryCount)
            {
                tryIndex++;
                try
                {
                    byte[] bufText = Encoding.Default.GetBytes(text);
                    stream.Write(bufText, 0, bufText.Length);
                    result = null;
                    break;
                }
                catch (Exception ex)
                {
                    result = ex;
                    Thread.Sleep(300);
                }
            }
            if (result != null)
            {
                return result;
            }
            return result;
        }


        public void Dispose()
        {
            Stop();
        }
    }
}

服务器

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Threading;

namespace NewCMS.Repositories
{
    public class MonitorMiniStoreTcpServerOwn : IDisposable
    {
        public int Port = 9090;
        public TcpListener tl = null;
        public Thread RunningThread = null;
        public List<Thread> RunningAcceptTcp = new List<Thread>();
        public List<MyTcpServerParam> AllConnections = new List<MyTcpServerParam>();
        public bool IsRunning = false;
        public string _Name = string.Empty;

        public virtual void Start(string name)
        {
            _Name = name;
            if (RunningThread != null)
            {
                Stop();
            }

            ThreadStart ts = new ThreadStart(StartThread);
            RunningThread = new Thread(ts);
            RunningThread.Start();
        }

        public virtual void StopWithoutAbort()
        {
            if (tl != null)
            {
                try
                {
                    tl.Stop();
                }
                catch { }
            }
            if (AllConnections != null)
            {
                try
                {
                    for (int i = AllConnections.Count - 1; i >= 0; i--)
                    {
                        if (AllConnections[i].Stream != null)
                        {
                            try
                            {
                                AllConnections[i].Stream.Close();
                            }
                            catch { }
                        }
                    }
                    AllConnections.Clear();
                }
                catch { }
            }
            if (RunningAcceptTcp != null)
            {
                try
                {
                    for (int i = RunningAcceptTcp.Count - 1; i >= 0; i--)
                    {
                        try
                        {
                            RunningAcceptTcp[i].Abort();
                        }
                        catch { }
                    }
                    RunningAcceptTcp.Clear();
                }
                catch { }
            }
        }

        public virtual void Stop()
        {
            try
            {
                IsRunning = false;
                if (tl != null)
                {
                    try
                    {
                        tl.Stop();
                    }
                    catch (Exception ex)
                    {
                    }
                }

                if (AllConnections != null)
                {
                    try
                    {
                        for (int i = AllConnections.Count - 1; i >= 0; i--)
                        {
                            if (AllConnections[i].Stream != null)
                            {
                                try
                                {
                                    AllConnections[i].Stream.Close();
                                }
                                catch { }
                            }
                        }
                        AllConnections.Clear();
                    }
                    catch { }
                }
                if (RunningAcceptTcp != null)
                {
                    try
                    {
                        for (int i = RunningAcceptTcp.Count - 1; i >= 0; i--)
                        {
                            try
                            {
                                RunningAcceptTcp[i].Abort();
                            }
                            catch { }
                        }
                        RunningAcceptTcp.Clear();
                    }
                    catch { }
                }
                if (RunningThread != null)
                {
                    try
                    {
                        RunningThread.Abort();
                    }
                    catch { }
                }
            }
            catch
            {
            }
        }

        protected void StartThread()
        {
            int retry = 0;
            IsRunning = true;
            while (IsRunning)
            {
                try
                {
                    tl = new TcpListener(IPAddress.Any, Port);
                    tl.Server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1);
                    tl.Start();
                    break;
                }
                catch (Exception ex)
                {
                    Thread.Sleep(1000);
                    retry++;
                }
            }
            while (IsRunning)
            {
                try
                {
                    TcpClient clientSocket = tl.AcceptTcpClient();
                    MyTcpServerParam p = new MyTcpServerParam();
                    p.Client = clientSocket;

                    ParameterizedThreadStart pts = new ParameterizedThreadStart(AcceptSocket);
                    Thread t = new Thread(pts);
                    //lock (RunningAcceptTcpSync)
                    {
                        RunningAcceptTcp.Add(t);
                    }
                    t.Start(p);
                }
                catch (Exception ex)
                {
                    StopWithoutAbort();
                    if (IsRunning)
                    {
                        ThreadStart ts = new ThreadStart(StartThread);
                        RunningThread = new Thread(ts);
                        RunningThread.Start();
                    }
                    break;
                }
            }
        }

        public void AcceptSocket(object obb)
        {
            try
            {
                if (IsRunning == false) return;
                byte[] bytesFrom = new byte[10025];
                string dataFromClient = string.Empty;

                MyTcpServerParam para = (MyTcpServerParam)obb;
                NetworkStream networkStream = para.Client.GetStream();
                para.Stream = networkStream;
                //lock (AllConnectionsSync)
                {
                    AllConnections.Add(para);
                }

                int read = 0;
                while ((read = networkStream.Read(bytesFrom, 0, bytesFrom.Length)) > 0)
                {
                    try
                    {
                        dataFromClient += System.Text.Encoding.ASCII.GetString(bytesFrom, 0, read);

                        string[] strs = dataFromClient.Split('\n');
                        if (strs != null)
                        {
                            for (int i = 0; i < strs.Length - 1; i++)
                            {
                                ProcessCommand(para, strs[i]);
                            }
                            if (dataFromClient.EndsWith("\n"))
                            {
                                ProcessCommand(para, strs[strs.Length - 1]);
                                dataFromClient = string.Empty;
                            }
                            else
                                dataFromClient = strs[strs.Length - 1];
                        }
                    }
                    catch (Exception ex)
                    {
                    }
                }
            }
            catch
            {
                try
                {
                    //lock (RunningAcceptTcpSync)
                    {
                        RunningAcceptTcp.Remove(Thread.CurrentThread);
                    }
                }
                catch { }
                try
                {
                    MyTcpServerParam para = (MyTcpServerParam)obb;
                    //lock (AllConnectionsSync)
                    {
                        AllConnections.Remove(para);
                    }
                }
                catch { }
            }
        }

        public virtual void ProcessCommand(MyTcpServerParam param, string str)
        {
        }

        public Exception SendData(MyTcpServerParam param, string text)
        {
            Exception result = null;
            int tryIndex = 0;
            int tryCount = 5;
            while (tryIndex < tryCount)
            {
                try
                {
                    tryIndex++;
                    byte[] bufText = Encoding.Default.GetBytes(text);
                    param.Stream.Write(bufText, 0, bufText.Length);
                    result = null;
                    break;
                }
                catch (Exception ex)
                {
                    result = ex;
                    Thread.Sleep(100);
                }
            }
            if (result != null)
            {
                try
                {
                    //lock (AllConnectionsSync)
                    {
                        AllConnections.Remove(param);
                    }
                }
                catch { }
                return result;
            }
            return result;
        }

        public void Dispose()
        {
            Stop();
        }
    }
}

0 个答案:

没有答案