欢迎光临
我们一直在努力

完整的TCP通信包实现-.NET教程,评论及其它

建站超值云服务器,限时71元/月

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;

}

}

赞(0)
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com 特别注意:本站所有转载文章言论不代表本站观点! 本站所提供的图片等素材,版权归原作者所有,如需使用,请与原作者联系。未经允许不得转载:IDC资讯中心 » 完整的TCP通信包实现-.NET教程,评论及其它
分享到: 更多 (0)

相关推荐

  • 暂无文章