Socket正在学习中
1,报文分析器
Code
/// <summary>
/// 数据报文分析器,通过分析接收到的原始数据,得到完整的数据报文.
/// 继承该类可以实现自己的报文解析方法.
/// 通常的报文识别方法包括:固定长度,长度标记,标记符等方法
/// 本类的现实的是标记符的方法,你可以在继承类中实现其他的方法
/// </summary>
public class DatagramResolver
{
/// <summary>
/// 报文结束标记
/// </summary>
private string endTag;
/// <summary>
/// 返回结束标记
/// </summary>
string EndTag
{
get
{
return endTag;
}
}
/// <summary>
/// 受保护的默认构造函数,提供给继承类使用
/// </summary>
protected DatagramResolver()
{
}
/// <summary>
/// 构造函数
/// </summary>
/// <param name="endTag">报文结束标记</param>
public DatagramResolver(string endTag)
{
if(endTag == null)
{
throw (new ArgumentNullException("结束标记不能为null"));
}
if(endTag == "")
{
throw (new ArgumentException("结束标记符号不能为空字符串"));
}
this.endTag = endTag;
}
/// <summary>
/// 解析报文
/// </summary>
/// <param name="rawDatagram">原始数据,返回未使用的报文片断,
/// 该片断会保存在Session的Datagram对象中</param>
/// <returns>报文数组,原始数据可能包含多个报文</returns>
public virtual string [] Resolve(ref string rawDatagram)
{
ArrayList datagrams = new ArrayList();
//末尾标记位置索引
int tagIndex =-1;
while(true)
{
tagIndex = rawDatagram.IndexOf(endTag,tagIndex+1);
if( tagIndex == -1 )
{
break;
}
else
{
//按照末尾标记把字符串分为左右两个部分
string newDatagram = rawDatagram.Substring(
0, tagIndex+endTag.Length);
datagrams.Add(newDatagram);
if(tagIndex+endTag.Length >= rawDatagram.Length)
{
rawDatagram="";
break;
}
rawDatagram = rawDatagram.Substring(tagIndex+endTag.Length,
rawDatagram.Length - newDatagram.Length);
//从开始位置开始查找
tagIndex=0;
}
}
string [] results= new string[datagrams.Count];
datagrams.CopyTo(results);
return results;
}
}
2,Session客户端类
Code
/// <summary>
/// 客户端与服务器之间的会话类
///
/// 版本: 1.1
/// 替换版本: 1.0
///
/// 说明:
/// 会话类包含远程通讯端的状态,这些状态包括Socket,报文内容,
/// 客户端退出的类型(正常关闭,强制退出两种类型)
/// </summary>
public class Session:ICloneable
{
#region 字段
/// <summary>
/// 会话ID
/// </summary>
private SessionId _id;
/// <summary>
/// 客户端发送到服务器的报文
/// 注意:在有些情况下报文可能只是报文的片断而不完整
/// </summary>
private string _datagram;
/// <summary>
/// 客户端的Socket
/// </summary>
private Socket _cliSock;
/// <summary>
/// 客户端的退出类型
/// </summary>
private ExitType _exitType;
/// <summary>
/// 退出类型枚举
/// </summary>
public enum ExitType
{
NormalExit ,
ExceptionExit
};
#endregion
#region 属性
/// <summary>
/// 返回会话的ID
/// </summary>
public SessionId ID
{
get
{
return _id;
}
}
/// <summary>
/// 存取会话的报文
/// </summary>
public string Datagram
{
get
{
return _datagram;
}
set
{
_datagram = value;
}
}
/// <summary>
/// 获得与客户端会话关联的Socket对象
/// </summary>
public Socket ClientSocket
{
get
{
return _cliSock;
}
}
/// <summary>
/// 存取客户端的退出方式
/// </summary>
public ExitType TypeOfExit
{
get
{
return _exitType;
}
set
{
_exitType = value;
}
}
#endregion
#region 方法
/// <summary>
/// 使用Socket对象的Handle值作为HashCode,它具有良好的线性特征.
/// </summary>
/// <returns></returns>
public override int GetHashCode()
{
return (int)_cliSock.Handle;
}
/// <summary>
/// 返回两个Session是否代表同一个客户端
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public override bool Equals(object obj)
{
Session rightObj = (Session)obj;
return (int)_cliSock.Handle == (int)rightObj.ClientSocket.Handle;
}
/// <summary>
/// 重载ToString()方法,返回Session对象的特征
/// </summary>
/// <returns></returns>
public override string ToString()
{
string result = string.Format("Session:{0},IP:{1}",
_id,_cliSock.RemoteEndPoint.ToString());
//result.C
return result;
}
/// <summary>
/// 构造函数
/// </summary>
/// <param name="cliSock">会话使用的Socket连接</param>
public Session( Socket cliSock)
{
Debug.Assert( cliSock !=null );
_cliSock = cliSock;
_id = new SessionId( (int)cliSock.Handle);
}
/// <summary>
/// 关闭会话
/// </summary>
public void Close()
{
Debug.Assert( _cliSock !=null );
//关闭数据的接受和发送
_cliSock.Shutdown( SocketShutdown.Both );
//清理资源
_cliSock.Close();
}
#endregion
#region ICloneable 成员
object System.ICloneable.Clone()
{
Session newSession = new Session(_cliSock);
newSession.Datagram = _datagram;
newSession.TypeOfExit = _exitType;
return newSession;
}
#endregion
}

浙公网安备 33010602011771号