using System;
|
using System.Diagnostics;
|
using System.Net.Sockets;
|
using System.Threading;
|
|
namespace Bro.Common.Link
|
{
|
public delegate void OnMessageRecv(byte[] dataBuff);
|
|
/// <summary>
|
/// TCP客户端连接
|
/// </summary>
|
public class TCPClient : LinkBase
|
{
|
private static object synObj = new object();
|
// 服务器地址
|
public string ServerIP { get;set;}
|
// 服务器IP
|
public int ServerPort { get;set;}
|
// 初始化标示
|
public bool IsInited { get;set; }
|
|
public OnMessageRecv MessageRecv;
|
|
// TCP客户端
|
public TcpClient Client = new TcpClient();
|
|
private Thread pollTask;
|
|
// 停止标示
|
private bool bStop = false;
|
|
public TCPClient()
|
{
|
IsInited = false;
|
}
|
|
/// <summary>
|
/// 初始化
|
/// </summary>
|
/// <returns></returns>
|
public override bool Init()
|
{
|
Client = new TcpClient();
|
|
// 接收发送缓存大小
|
Client.SendBufferSize = 4096;
|
Client.ReceiveBufferSize = 4096;
|
|
// 读写超时
|
Client.SendTimeout = 2000;
|
Client.ReceiveTimeout = 100;
|
|
IsInited = true;
|
|
return true;
|
}
|
|
/// <summary>
|
/// 销毁
|
/// </summary>
|
public override void Fnit()
|
{
|
IsInited = false;
|
|
if ( null == Client )
|
{
|
return;
|
}
|
|
Client.Close();
|
}
|
|
/// <summary>
|
/// 连接服务器
|
/// </summary>
|
/// <returns></returns>
|
public override bool Open()
|
{
|
try
|
{
|
if ( Client.Connected )
|
{
|
Trace.TraceInformation("TCPClient:{0} dunpliated open", this.Desp);
|
return true;
|
}
|
|
Client.Connect(ServerIP, ServerPort);
|
|
//pollTask = new Thread(new ThreadStart(PollThread));
|
//pollTask.Start();
|
|
return true;
|
}
|
catch(Exception ex)
|
{
|
Trace.TraceError("TCPClient:{0} Open fail, ex:{1}-{2}", this.Desp, ex.Message, ex.StackTrace);
|
}
|
|
return false;
|
}
|
|
/// <summary>
|
/// 关闭连接
|
/// </summary>
|
public override void Close()
|
{
|
try
|
{
|
if ( !Client.Connected )
|
{
|
return;
|
}
|
bStop = true;
|
ClosePollTask();
|
Client.Close();
|
|
}
|
catch(Exception ex)
|
{
|
Trace.TraceError("TCPClient:{0} Close fail, ex:{1}-{2}", this.Desp, ex.Message, ex.StackTrace);
|
}
|
}
|
|
/// <summary>
|
/// 判断对方是否在线,强制重新连接
|
/// </summary>
|
public void ReConnect()
|
{
|
if(!Client.IsOnline())
|
{
|
Close();
|
Init();
|
Open();
|
}
|
}
|
|
/// <summary>
|
/// 接收数据
|
/// </summary>
|
/// <returns></returns>
|
public override int Recv(byte[] rcvBuf, int offset)
|
{
|
int rcvLen = -1;
|
|
if ( null == rcvBuf )
|
{
|
return -1;
|
}
|
|
try
|
{
|
var len = rcvBuf.Length - offset;
|
if ( len <= 0 )
|
{
|
return -1;
|
}
|
rcvLen = Client.GetStream().Read(rcvBuf, offset, len);
|
}
|
catch(Exception ex)
|
{
|
Trace.TraceError("TCPClient:{0} Recv fail, ex:{1}-{2}", this.Desp, ex.Message, ex.StackTrace);
|
return -1;
|
}
|
|
return rcvLen;
|
}
|
|
/// <summary>
|
/// 发送数据
|
/// </summary>
|
/// <param name="sndBuf"></param>
|
/// <param name="bufLen"></param>
|
public override bool Send(byte[] sndBuf, int offset, int len)
|
{
|
if ( null == sndBuf )
|
{
|
return false;
|
}
|
|
try
|
{
|
Client.GetStream().Write(sndBuf, offset, len);
|
|
return true;
|
}
|
catch(Exception ex)
|
{
|
Trace.TraceError("TCPClient:{0} Send fail, ex:{1}-{2}", this.Desp, ex.Message, ex.StackTrace);
|
}
|
|
return false;
|
}
|
|
public void ClosePollTask()
|
{
|
pollTask?.Abort();
|
}
|
|
public void StartPollTask()
|
{
|
pollTask = new Thread(new ThreadStart(PollThread));
|
pollTask.Start();
|
}
|
|
/// <summary>
|
/// 监听线程
|
/// </summary>
|
private void PollThread()
|
{
|
for (; ; )
|
{
|
lock (synObj)
|
{
|
if (bStop)
|
break;
|
|
var data = new byte[2048];
|
if (Recv(data, 0) > 0)
|
{
|
MessageRecv(data);
|
}
|
}
|
}
|
}
|
|
|
}
|
|
public static class TcpClientEx
|
{
|
public static bool IsOnline(this TcpClient c)
|
{
|
return !((c.Client.Poll(1000, SelectMode.SelectRead) && (c.Client.Available == 0)) || !c.Client.Connected);
|
}
|
}
|
}
|