using System;
using System.Diagnostics;
using System.Net.Sockets;
using System.Threading;
namespace Bro.Common.Link
{
public delegate void OnMessageRecv(byte[] dataBuff);
///
/// TCP客户端连接
///
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;
}
///
/// 初始化
///
///
public override bool Init()
{
Client = new TcpClient();
// 接收发送缓存大小
Client.SendBufferSize = 4096;
Client.ReceiveBufferSize = 4096;
// 读写超时
Client.SendTimeout = 2000;
Client.ReceiveTimeout = 100;
IsInited = true;
return true;
}
///
/// 销毁
///
public override void Fnit()
{
IsInited = false;
if ( null == Client )
{
return;
}
Client.Close();
}
///
/// 连接服务器
///
///
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;
}
///
/// 关闭连接
///
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);
}
}
///
/// 判断对方是否在线,强制重新连接
///
public void ReConnect()
{
if(!Client.IsOnline())
{
Close();
Init();
Open();
}
}
///
/// 接收数据
///
///
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;
}
///
/// 发送数据
///
///
///
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();
}
///
/// 监听线程
///
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);
}
}
}