using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
namespace TCPManager
{
///
/// 处理接收回来的数据,返回处理完的总字节数。
///
///
/// 从[0] 开始处理
///
public delegate int ParsePacketHandler(TCPConn conn, byte[] inBuf);
public class TCPConn
{
TimeSpan Heartbeat_Interval = TimeSpan.FromSeconds(5); // heartbeat包发送间隔时间,5秒
TimeSpan Silent_Time = TimeSpan.FromSeconds(30); // 单位ms没有收到任何东西的时间,1分钟
const int MAX_BUFFER = 20 * 0x4000;//20个大包, 大包的尺寸在FObjSys 定义
const int Send_Error_timer = 5000; // 5000ms
protected List in_buffer = new List(MAX_BUFFER);
protected int packet_start;
protected int packet_len;
protected List out_buffer = new List(MAX_BUFFER);
protected DateTime comm_time;
protected DateTime heartbeat_time = DateTime.Now;
///
/// 长时间没发东西事件
///
public event Action OutputIsEmptyWithLongTimeEvent;
///
/// 数据接收处理
///
public ParsePacketHandler ParsePacket = null;
public Socket sock;
protected bool first_poll = true;
public TCPConn()
{
}
public TCPConn(Socket sock)
{
this.sock = sock;
}
public virtual int SendPacket(byte[] buffer)
{
int len = buffer.Length;
out_buffer.AddRange(buffer);
return len;
}
protected virtual int Clear_Packet()
{
if (packet_start > 0)
{
in_buffer.RemoveRange(0, packet_start);
}
return in_buffer.Count();
}
int Send_Poll2()
{
if (out_buffer.Count() == 0)
{
if ((DateTime.Now - heartbeat_time) > Heartbeat_Interval)
{
if (OutputIsEmptyWithLongTimeEvent != null)
OutputIsEmptyWithLongTimeEvent(this);
}
else
return 0;
}
heartbeat_time = DateTime.Now;
return Send_Poll();
}
int Send_Poll()
{
int cnt_total = 0;
if (out_buffer.Count() == 0)
return 0;
while (out_buffer.Count() > 0)
{
int cnt;
try
{
cnt = sock.Send(out_buffer.ToArray());
}
catch (System.Net.Sockets.SocketException e)
{
if (e.SocketErrorCode == SocketError.WouldBlock)
break;
return -1;
}
if (cnt > 0)
{
out_buffer.RemoveRange(0, cnt);
cnt_total += cnt;
}
else
{
break;
}
}
return cnt_total;
}
int Receive_Poll()
{
int reclen_total = 0;
while (true)
{
int reclen;
try
{
reclen = sock.Available;
}
catch (System.Net.Sockets.SocketException e)
{
//FDEBUG.Debug.LogMessage(this, 10, "Receive_Poll e=" + e.ToString());
if (reclen_total == 0)
return -1;
else
return reclen_total;
}
if (reclen == 0)
return reclen_total;
byte[] buf = new byte[reclen];
try
{
reclen = sock.Receive(buf);
}
catch (System.Net.Sockets.SocketException e)
{
//FDEBUG.Debug.LogMessage(this, 10, "Receive_Poll e=" + e.ToString());
if (reclen_total == 0)
return -1;
else
return reclen_total;
}
if (reclen > 0)
{
in_buffer.AddRange(buf);
reclen_total += reclen;
comm_time = DateTime.Now;
}
}
}
protected void Init()
{
if (first_poll)
{
comm_time = DateTime.Now;
heartbeat_time = DateTime.Now;
first_poll = false;
}
}
public virtual int OnPoll()
{
int ret = 0;
Init();
int reclen = Receive_Poll();
if (reclen < 0)
{
ret = -1;
goto end;
}
else if (reclen == 0)
{
if ((DateTime.Now - comm_time) > Silent_Time)//长时间没收到东西
{
//FDEBUG.Debug.LogMessage(this, 10, "ERROR 超时出错!");
ret = -2;
goto end;
}
}
else
{
int len=ParsePacket(this,in_buffer.ToArray());
if (len > 0)
{
in_buffer.RemoveRange(0, len);
}
}
int sendlen = Send_Poll2();
if (sendlen < 0)
{
ret = -1;
goto end;
}
end:
if (ret != 0)
{
//连接断开
Enable = false;
}
return ret;
}
#region IFConn 成员
public event Action ConnectEvent;
protected bool isconnected = false;
public virtual bool IsConnected
{
get
{
return isconnected;
}
set
{
if (isconnected != value)
{
isconnected = value;
if (ConnectEvent != null)
ConnectEvent(this);
}
}
}
protected bool enable = false;
public bool Enable
{
get
{
return enable;
}
set
{
enable = value;
if (enable == false)
{
Stop();
}
}
}
protected virtual void Stop()
{
if (sock != null)
sock.Close();
IsConnected = false;
}
#endregion
#region IFConn 成员
public uint TranID
{
get;
set;
}
#endregion
}
}