王朝网络
分享
 
 
 

完整的TCP通信包实现

王朝c#·作者佚名  2006-12-17
宽屏版  字体: |||超大  

using System;

namespace Jh.Sockets

{

/// <summary>

/// 线程状态信号定义

/// </summary>

public enum JhThreadStatus

{

Stop, //停止

Running, //正在运行

Exit //已退出

}

/// <summary>

/// 线程状态参数

/// </summary>

class Parm

{

public Parm(object obj):this(JhThreadStatus.Stop,obj)

{

}

public Parm(JhThreadStatus nStatus,object obj)

{

Status = nStatus;

ObjParm = obj;

}

JhThreadStatus status;

object objParm;

/// <summary>

/// 上下文对象

/// </summary>

public object ObjParm

{

get

{

return objParm;

}

set

{

objParm = value;

}

}

/// <summary>

/// 控制状态

/// </summary>

public JhThreadStatus Status

{

get

{

return status;

}

set

{

status = value;

}

}

};

/// <summary>

/// 通讯数据处理接口

/// </summary>

public interface IObserver

{

//

// 数据处理入口

//

void Deal(CommData cd);

//

// 数据处理重载方法.如果不希望后面的处理者继续处理数据,则返回true,否则返回false;

//

bool OnDeal(CommData cd);

//

// 附加的自身初始化操作

//

bool Init();

//

// 提前初始化接口

//

bool BeforeInit();

//

// 初始化后处理接口

//

bool AfterInit();

//

// 删除前处理接口

//

bool BeforeExit();

//

// 下一个观察者

//

IObserver Next

{

get;

set;

}

//

// 上一个观察者

//

IObserver Prev

{

get;

set;

}

//

// 添加观察者到后面,如果已经存在链表中则不做任何操作

//

void Add(IObserver observer);

//

// 插入观察者到下一个观察者的前面

//

void Insert(IObserver observer);

//删除观察者

void Remove(IObserver observer);

//是否存在链表中

bool IsExist(IObserver observer);

}

/// <summary>

/// 通讯数据处理类的基类,只能派生

/// </summary>

public abstract class Observer : IObserver

{

/// <summary>

/// 数据处理入口.

/// </summary>

/// <param name="client">TcpClient类 实例</param>

/// <param name="s">内存数据流</param>

public void Deal(CommData cd)

{

cd.Data.Position = 0;

if (OnDeal(cd) == false) return ;

if (next != null)

{

next.Deal(cd);

}

return ;

}

/// <summary>

/// 数据处理重载方法.

/// </summary>

/// <param name="client">TcpClient类 实例</param>

/// <param name="s">内存数据流</param>

/// <returns>处理结果,如果不希望后面的处理者继续处理数据,则返回false,否则返回true;</returns>

public virtual bool OnDeal(CommData cd)

{

return true;

}

//附加的自身初始化操作

public virtual bool Init()

{

return true;

}

//提前初始化接口

public virtual bool BeforeInit()

{

return true;

}

//初始化后处理接口

public virtual bool AfterInit()

{

return true;

}

//删除前处理接口

public virtual bool BeforeExit()

{

return true;

}

//下一个观察者

IObserver next = null;

public IObserver Next

{

get

{

return next;

}

set

{

next = value;

}

}

//上一个观察者

IObserver prev = null;

public IObserver Prev

{

get

{

return prev;

}

set

{

prev = value;

}

}

//添加观察者

public void Add(IObserver observer)

{

if (this == observer) return;//已经存在

if (next == null)

{

next = observer;//达到最底端

next.Prev = this;

}

else next.Add(observer);//加到后面

}

/// <summary>

/// 插入观察者到下一个观察者的前面

/// </summary>

/// <param name="observer"></param>

public void Insert(IObserver observer)

{

//是否等于自己

if (this == observer) return;

//先查找是否已经存在链表中

if (Next != null && Next.IsExist(observer)) Next.Remove(observer);

//

observer.Next = Next;

if (Next != null) Next.Prev = observer;

Next = observer;

observer.Prev = this;

}

/// <summary>

/// 删除观察者

/// </summary>

/// <param name="observer"></param>

public void Remove(IObserver observer)

{

if (observer == this)

{

if (Prev != null) Prev.Next = Next;

if (Next != null) Next.Prev = Prev;

}

else

{

if (Next != null) Next.Remove(observer);

}

}

/// <summary>

/// 查找是否存在

/// </summary>

/// <param name="observer"></param>

/// <returns></returns>

public bool IsExist(IObserver observer)

{

if (observer == this) return true;

if (Next == null) return false;

else return Next.IsExist(observer);

}

}

/// <summary>

/// 日志处理基类,本身从通讯数据处理类的基类派生。

/// </summary>

class Log : Observer

{

public Log()

{

}

public Log(string slogfile)

{

LogFile = slogfile;

}

~Log()

{

}

// 日志文件带路径名称

private string logFile;

public string LogFile

{

get

{

return logFile;

}

set

{

logFile = value;

}

}

}

}

using System;

using System.Collections;

using System.IO;

using System.Threading;

namespace Jh.Sockets

{

/// <summary>

/// 数据集中管理类

/// </summary>

public class CommDataMgr

{

static int index = 0;

int id;

/// <summary>

/// 无参数构造方法

/// </summary>

public CommDataMgr()

{

id = index ++;

dnFlag = new Parm(this);

Console.WriteLine("JH data distributor {0} constructed",id);

}

Thread t = null;

public void Start()

{

if (dnFlag.Status != JhThreadStatus.Running)

{

dnFlag.Status = JhThreadStatus.Running;

t = new Thread (new ThreadStart(DataNotiyfyThread));

t.Name = "JH data distributing " + id.ToString();

t.Start();

Console.WriteLine("JH data distributing thread of JH data distributor {0} started",id);

}

}

public void Stop()

{

if ( dnFlag.Status == JhThreadStatus.Running )

{

lock (this)

{

dnFlag.Status = JhThreadStatus.Stop;

}

}

}

/// <summary>

/// 析构方法

/// </summary>

~CommDataMgr()

{

Stop();

Console.WriteLine("JH data distributor {0} unconstructed",id);

}

public void DataNotiyfyThread()

{

try

{

while (dnFlag.Status == JhThreadStatus.Running)

{

DealData();

Thread.Sleep(100);

// Console.WriteLine("分发线程{0}工作中",id);

}

}

catch(Exception e)

{

Console.WriteLine(e.Message);

}

finally

{

lock(this)

{

dnFlag.Status = JhThreadStatus.Exit;

}

Console.WriteLine("JH data distributing thread of JH data distributor {0} exited",id);

}

}

Parm dnFlag = null;

ArrayList aData = new ArrayList();

InnerObserver root = new InnerObserver();

/// <summary>

/// 观察者根节点类 定义

/// </summary>

internal class InnerObserver : Observer

{

}

public void DealData()

{

if (DataCount > 0)

{

lock(this)

{

if (root.Next != null)

{

root.Next.Deal((CommData)aData[0]);

}

RemoveAt(0);

}

}

}

/// <summary>

/// 未处理数据个数

/// </summary>

public int DataCount

{

get

{

return aData.Count;

}

}

/// <summary>

/// 根据索引返回未处理数据

/// </summary>

internal CommData this[int Index]

{

get

{

return (CommData)aData[Index];

}

}

/// <summary>

/// 根据索引删除数据

/// </summary>

/// <param name="Index">索引</param>

public void RemoveAt(int Index)

{

if (Index >= 0 && Index < DataCount)

{

lock (this)

{

aData.RemoveAt(Index);

}

}

}

/// <summary>

/// 接收到新的数据提交

/// </summary>

/// <param name="client">客户端连接</param>

/// <param name="s">数据流</param>

public void AddData(JhClient client,MemoryStream s,int len)

{

CommData cd = new CommData(client,s,len,this);

lock(this)

{

aData.Add(cd);

}

}

/// <summary>

/// 添加观察者

/// </summary>

/// <param name="observer"></param>

public void Add(IObserver observer)

{

lock (this)

{

root.Add(observer);

}

}

/// <summary>

/// 删除观察者

/// </summary>

/// <param name="observer"></param>

public void Remove(IObserver observer)

{

lock (this)

{

root.Remove(observer);

}

}

/// <summary>

/// 在最前面插入观察者

/// </summary>

/// <param name="observer"></param>

public void Insert(IObserver observer)

{

lock (this)

{

root.Insert(observer);

}

}

// 取观察者个数

// int GetObserverCount()

// {

// return (int)m_aObservers.GetCount();

// }

}

}

using System;

using System.Threading;

using System.Net.Sockets;

using System.IO;

using System.Collections;

using System.Windows.Forms;

using System.Net;

namespace Jh.Sockets

{

/// <summary>

/// 内部通信消息

/// </summary>

enum JhCommMessages

{

MessageStart = 9909,//消息起始

DataTransfer, //数据传输

Disconnected, //连接将要断开

ConnectSignal, //连接检查信号

ConnectCheck, //启动连接信号

StopCheck, //停止连接信号

Unknown = 9999 //未知

}

/// <summary>

/// 通信数据

/// </summary>

public class CommData

{

public CommData(JhClient client,MemoryStream stream,int len,CommDataMgr dm)

{

jhClient = client;

Data = new MemoryStream();

stream.WriteTo(Data);

dataLen = len;

adm = dm;

}

JhClient jhClient;

MemoryStream data;

int dataLen;

CommDataMgr adm;

/// <summary>

/// tcp连接

/// </summary>

public JhClient Socket

{

get

{

return jhClient;

}

}

/// <summary>

/// 内存数据流

/// </summary>

public MemoryStream Data

{

get

{

return data;

}

set

{

data = value;

}

}

/// <summary>

/// 数据长度

/// </summary>

public int DataLen

{

get

{

return dataLen;

}

}

};

public delegate void CommEventHandler(object sender,CommEventArgs e);

public class CommEventArgs : EventArgs

{

public CommEventArgs(string msg):base()

{

Message = msg;

}

string message;

public string Message

{

get

{

return message;

}

set

{

message = value;

}

}

}

/// <summary>

/// Tcp通信客户类

/// </summary>

public class JhClient

{

/// <summary>

/// 连接成功事件

/// </summary>

public event CommEventHandler OnConnected;

/// <summary>

/// 连接关闭事件

/// </summary>

public event CommEventHandler OnClosed;

/// <summary>

/// 连接失败事件

/// </summary>

public event CommEventHandler OnConnectFailed;

/// <summary>

/// 构造方法

/// </summary>

/// <param name="dm">外部植入的数据管理类</param>

/// <param name="ob">观察者</param>

/// <param name="tcpClient">通信连接</param>

public JhClient(CommDataMgr dm,IObserver ob,TcpClient tcpClient)

{

//

// TODO: 在此处添加构造函数逻辑

//

status = new Parm(this);

checkStatus = new Parm(this);

autoConnectStatus = new Parm(this);

if (dm == null)

{

adm = new CommDataMgr();

}

else adm = dm;

if (ob != null) adm.Add(ob);

if (tcpClient == null)

{

client = new TcpClient();

}

else client = tcpClient;

ID = index ++;

OnClosed += new CommEventHandler(OnConnectClosed);

Console.WriteLine("JH tcp client {0} constructed",ID);

}

static int index = 0;

/// <summary>

/// 无参数构造函数

/// </summary>

public JhClient(TcpClient tcpClient) : this(null,null,tcpClient)

{}

public JhClient(CommDataMgr dm,TcpClient tcpClient) : this(dm,null,tcpClient)

{}

public JhClient(IObserver ob,TcpClient tcpClient):this(null,ob,tcpClient)

{}

public JhClient() : this(null,null,null)

{}

public JhClient(CommDataMgr dm) : this(dm,null,null)

{}

public JhClient(IObserver ob):this(null,ob,null)

{}

/// <summary>

/// 析构方法

/// </summary>

~JhClient()

{

AutoConnect = false;

ConnectCheck = false;

Close();

Console.WriteLine("JH tcp client {0} unconstructed",ID);

}

Parm status = null;

/// <summary>

/// 唯一标志符

/// </summary>

int id = -1;

public int ID

{

get

{

return id;

}

set

{

id = value;

}

}

/// <summary>

/// 连接状态

/// </summary>

bool connected = false;

public bool Connected

{

get

{

return connected;

}

set

{

connected = value;

if (connected == true)

{

adm.Start();

if (status.Status != JhThreadStatus.Running)

{

status.Status = JhThreadStatus.Running;

readThread = new Thread(new ThreadStart(this.DataReadThread));

readThread.Name = "Data reader of JH tcp client " + ID.ToString();

readThread.Start();

Console.WriteLine("Data reader of JH tcp client {0} started",ID);

LastReceivedTime = DateTime.Now;

if (ConnectCheck == true)

{

SendMessage(JhCommMessages.ConnectCheck,(Int32)CheckTimeout.Ticks);

StartConnectCheckThread();

}

}

}

else

{

status.Status = JhThreadStatus.Stop;

if (OnClosed != null) OnClosed(this,new CommEventArgs("连接已经断开!"));

}

}

}

/// <summary>

/// 尝试连接次数

/// </summary>

int connectTimes = 0;

/// <summary>

/// 读取数据线程

/// </summary>

Thread readThread = null;

/// <summary>

/// 自动断线重连标志

/// </summary>

bool autoConnect = false;

/// <summary>

/// 自动断线重连标志

/// </summary>

public bool AutoConnect

{

get

{

return autoConnect;

}

set

{

autoConnect = value;

if (autoConnect != true)

{

lock(this)

{

autoConnectStatus.Status = JhThreadStatus.Stop;

}

}

}

}

/// <summary>

/// 自动连接间隔毫秒数

/// </summary>

int autoConnectInterval = 3000;

/// <summary>

/// 自动连接间隔毫秒数

/// </summary>

public int AutoConnectInterval

{

get

{

return autoConnectInterval;

}

set

{

autoConnectInterval = value;

}

}

/// <summary>

/// 连接检测的状态控制

/// </summary>

Parm checkStatus = null;

/// <summary>

/// 自动连接的状态控制

/// </summary>

Parm autoConnectStatus = null;

/// <summary>

/// 连接监测标志

/// </summary>

bool connectCheck = false;

/// <summary>

/// 连接监测标志

/// </summary>

public bool ConnectCheck

{

get

{

return connectCheck;

}

set

{

bool b = value;

if (connectCheck != b)

{

if (connectCheck != true)//启动检测

{

lock(this)

{

checkStatus.Status = JhThreadStatus.Stop;

}

if (Connected == true)

{

SendMessage(JhCommMessages.StopCheck);

}

}

else

{

if (Connected == true) StartConnectCheckThread();

}

}

}

}

/// <summary>

/// 启动连接检测线程

/// </summary>

void StartConnectCheckThread()

{

if (checkStatus.Status != JhThreadStatus.Running)

{

checkStatus.Status = JhThreadStatus.Running;

Thread t = new Thread(new ThreadStart(ConnectCheckThread));

t.Name = "JH tcp client connecting checker of JH tcp client " + this.ID.ToString();

t.Start();

Console.WriteLine(t.Name + " started.");

}

}

/// <summary>

/// 连接关闭事件响应

/// </summary>

/// <param name="sender"></param>

/// <param name="e"></param>

public virtual void OnConnectClosed(object sender,CommEventArgs e)

{

if (AutoConnect == true)//是否自动重连

{

StartAutoConnectThread();

}

}

/// <summary>

/// 启动自动重连线程

/// </summary>

void StartAutoConnectThread()

{

if (autoConnectStatus.Status != JhThreadStatus.Running)

{

connectTimes = 0;

autoConnectStatus.Status = JhThreadStatus.Running;

Thread t = new Thread(new ThreadStart(AutoConnectThread));

t.Name = "JH tcp client auto-connector of JH tcp client " + this.ID.ToString();

t.Start();

Console.WriteLine(t.Name + " started.");

}

}

/// <summary>

/// 最近一次通讯时间

/// </summary>

DateTime lastReceivedTime = DateTime.Now;

/// <summary>

/// 最近一次通讯时间

/// </summary>

public DateTime LastReceivedTime

{

get

{

return lastReceivedTime;

}

set

{

lastReceivedTime = value;

}

}

/// <summary>

/// 连接检测断开判断的最大允许毫秒数

/// </summary>

TimeSpan checkTimeout = new TimeSpan(1800000000);//3 minutes

/// <summary>

/// 连接检测断开判断的最大允许毫秒数

/// </summary>

public TimeSpan CheckTimeout

{

get

{

return checkTimeout;

}

set

{

TimeSpan ts = value;

if (ts.Minutes > 2) checkTimeout = ts;//检查时间间隔不小于2分钟

}

}

/// <summary>

/// 自动连接线程

/// </summary>

void AutoConnectThread()

{

try

{

while (autoConnectStatus.Status == JhThreadStatus.Running && AutoConnect == true)

{

if (Connected != true)

{

DoConnect();

Thread.Sleep(AutoConnectInterval);

}

else

{

break;

}

}

}

catch (Exception e3)

{

MessageBox.Show(e3.Message);

}

finally

{

lock (this)

{

autoConnectStatus.Status = JhThreadStatus.Exit;

}

}

}

/// <summary>

/// 连接检测线程

/// </summary>

void ConnectCheckThread()

{

try

{

while (checkStatus.Status == JhThreadStatus.Running)

{

if (Connected == true)

{

TimeSpan ts = DateTime.Now - lastReceivedTime;

TimeSpan ts2 = CheckTimeout + CheckTimeout;

if (ts > ts2 )//超过两倍间隔时间,认为已经断开

{

Close();

break;

}

else

{

SendMessage(JhCommMessages.ConnectSignal,(Int32)CheckTimeout.Ticks);

}

}

else

{

LastReceivedTime = DateTime.Now;

break;

}

Thread.Sleep(checkTimeout);

}

}

catch (Exception e3)

{

MessageBox.Show(e3.Message);

}

finally

{

lock(this)

{

checkStatus.Status = JhThreadStatus.Exit;

}

Console.WriteLine("JH tcp client connecting checker of JH tcp client " + this.ID.ToString() + " exited.") ;

}

}

/// <summary>

/// 读取数据的线程

/// </summary>

void DataReadThread()

{

try

{

while (status.Status == JhThreadStatus.Running)

{

if (Connected == true)

{

NetworkStream ns = Client.GetStream();

int readCount,totalRead = 0;

while (ns.DataAvailable == true)//读取数据,转存到s中,因为NetworkStream的数据只能向前读取一次

{

readCount = ns.Read(buffer, 0, bufferSize);

if (readCount > 0)

{

buf.Write(buffer, 0, readCount);

totalRead += readCount;

}

else

{

break;

}

} ;

if (totalRead > 0)//有数据

{

DealData();//处理

}

}

Thread.Sleep(50);

}

}

catch(IOException e3)

{

MessageBox.Show(e3.Message);

}

catch (ObjectDisposedException e2)

{

MessageBox.Show(e2.Message);

}

catch (InvalidOperationException e1)

{

MessageBox.Show(e1.Message);

}

catch (Exception e3)

{

MessageBox.Show(e3.Message);

}

finally

{

lock(this)

{

status.Status = JhThreadStatus.Exit;

}

Console.WriteLine("Data reader thread of JH tcp client {0} exited.",ID);

}

}

/// <summary>

/// 服务器ip

/// </summary>

string ipString;

/// <summary>

/// 服务器端口

/// </summary>

int tcpPort;

/// <summary>

/// 根据当前设置的ip和 port参数进行连接

/// </summary>

void DoConnect()

{

try

{

if (Connected == false)

{

if (Client == null)

{

Client = new TcpClient();

}

++ connectTimes ;

Client.Connect(ipString,tcpPort);

Connected = true;

autoConnectStatus.Status = JhThreadStatus.Stop;

if (OnConnected != null) OnConnected(this,new CommEventArgs("已经与服务器建立连接!"));

}

}

catch(Exception le)

{

if (OnConnectFailed != null) OnConnectFailed(this,new CommEventArgs("第" + connectTimes.ToString() + "次与服务器建立连接失败!" + le.Message));

}

}

/// <summary>

/// 连接服务器

/// </summary>

/// <param name="ip"></param>

/// <param name="port"></param>

public void Connect(string ip,int port)

{

ipString = ip;

tcpPort = port;

if (this.AutoConnect == true)

{

StartAutoConnectThread();

}

else

{

DoConnect();

}

}

/// <summary>

/// 发送数据

/// </summary>

/// <param name="data"></param>

/// <returns></returns>

public void Send(string data)

{

Send( data, System.Text.Encoding.Default);

}

/// <summary>

/// 发送数据

/// </summary>

/// <param name="data"></param>

/// <returns></returns>

public void Send(string data, System.Text.Encoding encodingway)

{

byte[] dt = encodingway.GetBytes(data);

Send(dt);

}

/// <summary>

/// 发送数据

/// </summary>

/// <param name="data"></param>

/// <returns></returns>

public void Send(byte[] data)

{

if (Connected == true)

{

CommHead ch = new CommHead();

ch.WParam = (short)JhCommMessages.DataTransfer;

ch.Add(data);

client.GetStream().Write(ch.ToBytes(),0,ch.Length);

}

else

{

MessageBox.Show("尚未建立连接或者连接已经断开!");

}

}

/// <summary>

/// 关闭连接

/// </summary>

public void Close()

{

if (Connected == true)

{

SendMessage(JhCommMessages.Disconnected);

Connected = false;

adm.Stop();

Client.Close();

Client = null;

}

}

/// <summary>

/// 程序退出时调用,或者设置AutoConnect = false

/// </summary>

public void Exit()

{

AutoConnect = false;

ConnectCheck = false;

Close();

}

/// <summary>

/// TCP客户对象

/// </summary>

TcpClient client = null;

/// <summary>

/// TCP客户对象

/// </summary>

public TcpClient Client

{

get

{

return client;

}

set

{

client = value;

}

}

/// <summary>

/// 缓存未处理的数据

/// </summary>

MemoryStream buf = new MemoryStream();

/// <summary>

/// 读取接收到的数据的缓冲区的大小

/// </summary>

const int bufferSize = 1024;

/// <summary>

/// 读取接收到的数据的缓冲区

/// </summary>

byte[] buffer = new byte[bufferSize];

/// <summary>

/// 数据分发管理者

/// </summary>

CommDataMgr adm ;

/// <summary>

/// 数据分发管理者

/// </summary>

public CommDataMgr DataMgr

{

set

{

adm = value;

}

}

/// <summary>

/// 接收到的数据的处理

/// </summary>

private void DealData()

{

// if (buf.Length > 0) //有数据需要处理

{

CommHead chio = new CommHead(buf,(int)buf.Position);

if (chio.IsValid())

{

LastReceivedTime = DateTime.Now;

if (chio.DataLen > 0)//有效数据

{

adm.AddData(this,chio.GetData(),chio.DataLen);//可处理数据

}

else//纯内部消息

{

switch ((JhCommMessages)chio.WParam)

{

case JhCommMessages.Disconnected: //对方将要断开连接消息

Close();

break;

case JhCommMessages.ConnectCheck:

if (CheckTimeout.Ticks != chio.DWParam)

{

CheckTimeout = new TimeSpan(chio.DWParam);

}

ConnectCheck = true;

break;

case JhCommMessages.StopCheck:

ConnectCheck = false;

break;

case JhCommMessages.ConnectSignal:

if (CheckTimeout.Ticks != chio.DWParam)

{

CheckTimeout = new TimeSpan(chio.DWParam);

}

break;

default:

break;

}

}

buf.Position = 0;

chio.GetLeftData(ref buf);//剩下未处理完数据

}

}

}

/// <summary>

/// 不带参数的消息

/// </summary>

/// <param name="message"></param>

private void SendMessage(JhCommMessages message)

{

SendMessage(message,0);

}

/// <summary>

/// 带参数的消息

/// </summary>

/// <param name="message"></param>

private void SendMessage(JhCommMessages message,Int32 parm)

{

CommHead ch = new CommHead();

ch.WParam = (short)message;

ch.DWParam = parm;

Client.GetStream().Write(ch.ToBytes(),0,16);

}

}

/// <summary>

/// Tcp通信服务器类

/// </summary>

public class JhTcpServer

{

public JhTcpServer(int port)

{

IPAddress ipAddress = IPAddress.Parse("127.0.0.1");//Dns.Resolve("localhost").AddressList[0];

server = new TcpListener(ipAddress,port);

adm = new CommDataMgr();

status = new Parm(this);

}

~JhTcpServer()

{

Stop();

}

/// <summary>

/// Tcp监听对象

/// </summary>

TcpListener server = null;

/// <summary>

/// 客户端序号

/// </summary>

int clientindex = 0;

/// <summary>

/// 开始监听

/// </summary>

public void Start()

{

clients.Clear();

clientindex = 99999999;

adm.Start();

server.Start();

status.Status = JhThreadStatus.Running;

listenThread = new Thread(new ThreadStart(this.ListenThread));

listenThread.Name = "JH tcp listenor";

listenThread.Start();

Console.WriteLine("JH tcp listenor started.");

}

/// <summary>

/// 监听线程

/// </summary>

Thread listenThread = null;

/// <summary>

/// 停止接受连接

/// </summary>

public void Stop()

{

int i;

for (i = 0; i < this.clients.Count; ++i)

{

StopClient(i);

}

adm.Stop();

if (status.Status == JhThreadStatus.Running)

{

lock(this)

{

status.Status = JhThreadStatus.Stop;

}

while (status.Status != JhThreadStatus.Exit)

{

Thread.Sleep(100);

}

}

server.Stop();

}

/// <summary>

/// 断开指定索引的客户

/// </summary>

/// <param name="index">客户端索引</param>

public void StopClient(int index)

{

GetClient(index).Exit();

}

/// <summary>

/// 发送数据

/// </summary>

/// <param name="data"></param>

/// <returns></returns>

public void Send(JhClient client,string data)

{

if (client != null)

{

byte[] dt = System.Text.Encoding.Default.GetBytes(data);

client.Send(dt);

}

}

/// <summary>

/// 用最后一个客户端发送数据

/// </summary>

/// <param name="data"></param>

public void Send(string data)

{

Send(GetClient(clients.Count - 1),data);

}

/// <summary>

/// 数据分发管理者

/// </summary>

CommDataMgr adm ;

Parm status = null;

/// <summary>

/// 客户连接线程

/// </summary>

void ListenThread()

{

try

{

while (status.Status == JhThreadStatus.Running)

{

if (server.Pending() == true)

{

TcpClient client = server.AcceptTcpClient();//侦听到连接后创建客户端

JhClient jhClient = new JhClient(adm,client);

jhClient.ID = clientindex--;

SetClient(jhClient);

jhClient.Connected = true;

}

Thread.Sleep(100);

}

}

catch (ObjectDisposedException e2)

{

MessageBox.Show(e2.Message);

}

catch (InvalidOperationException e1)

{

MessageBox.Show(e1.Message);

}

catch (Exception e3)

{

MessageBox.Show(e3.Message);

}

finally

{

lock(this)

{

status.Status = JhThreadStatus.Exit;

}

Console.WriteLine("JH tcp listenor exited");

}

}

/// <summary>

/// 添加观察者

/// </summary>

/// <param name="ob"></param>

public void AddOb(IObserver ob)

{

adm.Add(ob);

}

Hashtable clients = new Hashtable();

/// <summary>

/// 根据内部id获取客户端

/// </summary>

/// <param name="id"></param>

/// <returns></returns>

public JhClient GetClient(int id)

{

return (JhClient)clients[id];

}

/// <summary>

/// 设置客户端对象

/// </summary>

/// <param name="client"></param>

public void SetClient(JhClient client)

{

int i;

for (i = 0 ; i < clients.Count; ++i)

{

if (((JhClient)clients[i]).ID == client.ID)

{

break;

}

}

clients[i] = client;

}

}

/// <summary>

/// 通信头处理类

/// </summary>

class CommHead

{

Int16 wHeadSize;// 头结构长度

Int16 wFlag;//合法数据包特征字

Int16 wVer;// 用版本号表示标识符

Int16 wParm;// 参数一

Int32 dwParm;// 参数二

Int32 dwDataLen;// 后续数据长度

/// <summary>

/// 新建头构造方法

/// </summary>

public CommHead() : this(System.Text.Encoding.Default)

{

Init();

}

/// <summary>

/// 新建头构造方法

/// </summary>

public CommHead(System.Text.Encoding enCoding)

{

encoding = enCoding;

Init();

}

System.Text.Encoding encoding;

/// <summary>

/// 解析数据构造方法

/// </summary>

/// <param name="s">数据流</param>

public CommHead(MemoryStream s,int len) : this(s,len,System.Text.Encoding.Default)

{

}

/// <summary>

/// 解析数据构造方法

/// </summary>

/// <param name="s">数据流</param>

/// <param name="encoding">字符编码方案</param>

public CommHead(MemoryStream s,int len,System.Text.Encoding encoding)

{

Init();

if (s != null)

{

s.Position = 0;

BinaryReader r = new BinaryReader(s,encoding);

wHeadSize = r.ReadInt16();

if (len >= wHeadSize)

{

wFlag = r.ReadInt16();

if (IsValid())

{

wVer = r.ReadInt16();

wParm = r.ReadInt16();

dwParm = r.ReadInt32();

dwDataLen = r.ReadInt32();

if (dwDataLen > 0)

{

byte[] dt = r.ReadBytes(dwDataLen);

if (dt != null) recvData = new MemoryStream(dt);

else

{

recvData = null;

dwDataLen = 0;

}

}

if (len > wHeadSize + dwDataLen)

{

byte[] dt = r.ReadBytes(len - wHeadSize - dwDataLen);

if (dt != null) moreData = new MemoryStream(dt);

else moreData = null;

}

}

}

}

}

MemoryStream recvData;

MemoryStream moreData;

void Init() {wFlag = 0x4a48; wVer = 1; wHeadSize = 16; }

// 当前头数据是否有效

public bool IsValid() {return wFlag == 0x4a48 && wHeadSize == 16; }

// 返回双字节参数

public Int32 DWParam

{

get

{

return dwParm;

}

set

{

dwParm = value;

}

}

// 返回单字节参数

public Int16 WParam

{

get

{

return wParm;

}

set

{

wParm = value;

}

}

// 返回头结构大小

public Int16 HeadSize

{

get

{

return wHeadSize;

}

}

// 返回版本标识符

public virtual Int16 Ver

{

get

{

return wVer;

}

}

// 返回后续数据长度

public virtual Int32 DataLen

{

get

{

return dwDataLen;

}

set

{

dwDataLen = value;

}

}

/// <summary>

/// 返回未处理数据

/// </summary>

/// <returns></returns>

public void GetLeftData(ref MemoryStream s)

{

if (moreData != null)

{

moreData.WriteTo(s);

moreData.Close();

}

}

/// <summary>

/// 返回完整数据

/// </summary>

/// <returns></returns>

public MemoryStream GetData()

{

return recvData;

}

/// <summary>

/// 添加数据

/// </summary>

/// <param name="pszData"></param>

public void Add(byte[] pszData)

{

data.Write(pszData,0,pszData.Length);

dwDataLen += pszData.Length;

}

MemoryStream data = new MemoryStream();

/// <summary>

/// 需要发送的数据转为字节数组

/// </summary>

/// <returns></returns>

public byte[] ToBytes()

{

MemoryStream s = new MemoryStream();

BinaryWriter w = new BinaryWriter(s,encoding);

w.Write(wHeadSize);

w.Write(wFlag);

w.Write(wVer);

w.Write(wParm);

w.Write(dwParm);

w.Write(dwDataLen);

// w.Close();

data.WriteTo(s);

return s.ToArray();

}

/// <summary>

/// 需要发送的数据的长度

/// </summary>

public int Length

{

get

{

return (int)data.Length + wHeadSize;

}

}

}

}

namespace Jh.Sockets

{

/// <summary>

/// 字符串特性常量存放类

/// </summary>

public class JhStringConst

{

public const int SHORT_STRING_LEN = 16;

public const int NORMAL_STRING_LEN = 32;

public const int MIDD_STRING_LEN = 64;

public const int LONG_STRING_LEN = 128;

public const int LONGER_STRING_LEN = 256;

public const int EXLONG_STRING_LEN = 1024;

}

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
>>返回首页<<
推荐阅读
 
 
频道精选
 
静静地坐在废墟上,四周的荒凉一望无际,忽然觉得,凄凉也很美
© 2005- 王朝网络 版权所有