我正在创建一个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();
}
}
}