异步TCP客户端实现断线自动重连
在网上找了一个例子,测试发现了一些问题,主要是服务端没有开启,客户端就开启失败,物理网络断开后,无法自动连接。 修改后客户端实现了,被服务端踢下线,自动重连,等待服务端开启后,自动连接,物理网络断开恢复后,自动重连功能,亲自测试,功能完整。 客户端需要心跳发送,不然,物理网络断开恢复后,自动重连功能不能实现。
调用TCP客户端
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Timers;
using LJF;
class Program
{
private static string _ip = "192.168.0.10";
private static int _port = 8000;
static void Main(string[] args)
{
AsyncTcpClient lJF = new AsyncTcpClient();
lJF.ConnectServer(_ip, _port);
while (true)
{
Thread.Sleep(1000);
lJF.SendMsg("heartbeat");
}
}
}
异步TCP客户端
using System.Net;
using System;
using System.Text;
using System.Diagnostics;
using System.IO;
namespace LJF
{
public class AsyncTcpClient
{
private string ip1;
private int port1;
byte[] ReadBytes = new byte[1024 * 1024];
public static bool isWrite = false;
public static AsyncTcpClient Instance
{
get
{
if (instance == null)
{
instance = new AsyncTcpClient();
}
return instance;
}
}
private static AsyncTcpClient instance;
System.Net.Sockets.TcpClient tcpClient;
public void ConnectServer(string ip, int port)
{
ip1 = ip;
port1 = port;
try
{
tcpClient = new System.Net.Sockets.TcpClient();
tcpClient.BeginConnect(IPAddress.Parse(ip), port, Lianjie, null);
}
catch (Exception e)
{
displayDebug("初始化连接错误---," + e.Message);
}
}
void Lianjie(IAsyncResult ar)
{
if (!tcpClient.Connected)
{
displayDebug("判断连接---,服务器未开启,尝试重连。。。。。。");
tcpClient = null;
try
{
ConnectServer(ip1, port1);
}
catch (Exception e)
{
displayDebug("判断连接---从新连接错误," + e.Message);
}
}
else
{
displayDebug("判断连接---,连接上了");
try
{
tcpClient.EndConnect(ar);
tcpClient.GetStream().BeginRead(ReadBytes, 0, ReadBytes.Length, ReceiveCallBack, null);
isWrite = true;
}
catch (Exception e)
{
displayDebug("判断连接错误---," + e.Message);
}
}
}
void ReceiveCallBack(IAsyncResult ar)
{
try
{
int len = tcpClient.GetStream().EndRead(ar);
if (len > 0)
{
string str = Encoding.GetEncoding("GB2312").GetString(ReadBytes, 0, len);
str = Uri.UnescapeDataString(str);
displayDebug(str);
writerCsv(getTime(str), "log");
tcpClient.GetStream().BeginRead(ReadBytes, 0, ReadBytes.Length, ReceiveCallBack, null);
}
else
{
tcpClient = null;
displayDebug("接收消息---连接断开,尝试重连。。。。。。");
ConnectServer(ip1, port1);
}
}
catch (Exception e)
{
displayDebug("接收消息错误---," + e.Message);
tcpClient = null;
displayDebug("接收消息错误---网络断开,尝试重连。。。。。。");
ConnectServer(ip1, port1);
}
}
public void SendMsg(string msg)
{
try
{
if (tcpClient != null && tcpClient.Client.Connected)
{
byte[] msgBytes = Encoding.GetEncoding("GB2312").GetBytes(msg);
tcpClient.GetStream().BeginWrite(msgBytes, 0, msgBytes.Length, (ar) =>
{
tcpClient.GetStream().EndWrite(ar);
}, null);
}
else
{
displayDebug("发送消息---,网络断开,尝试重连。。。。。。");
}
}
catch (Exception e)
{
displayDebug("发送消息错误---," + e.Message);
}
}
public void Close()
{
if (tcpClient != null && tcpClient.Client.Connected)
tcpClient.Close();
if (!tcpClient.Client.Connected)
{
tcpClient.Close();
}
}
private void writerCsv(String data, string name)
{
try
{
string mTime = DateTime.Now.ToString("yyyyMMdd");
string currPath = System.AppDomain.CurrentDomain.BaseDirectory;
string subPath = currPath + "\\login\\";
if (false == System.IO.Directory.Exists(subPath))
{
System.IO.Directory.CreateDirectory(subPath);
}
subPath += mTime + name + ".csv";
FileStream fs = new FileStream(subPath, FileMode.Append);
StreamWriter sw = new StreamWriter(fs, System.Text.Encoding.Default);
sw.WriteLine(data);
sw.Flush();
sw.Close();
fs.Close();
}
catch (Exception)
{
displayDebug("数据保存失败!");
}
}
private void displayDebug(string msg)
{
string log = getTime(msg);
Console.WriteLine(log);
}
private string getTime(string msg)
{
string mTime = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
mTime += " : ";
mTime += msg;
return mTime;
}
}
}
|