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;
}
}
