CS通用模型设计,socket,tcp实现(-)
2010-01-19 00:54 杨兴亚 阅读(2396) 评论(18) 编辑 收藏 举报最近,一直在做一个手机为客户端的CS系统了,10月份开始的,现在又将近4个月了,现在对
它做一个简单的总结。
1.功能简介:
通过服务器向手机终端发送命令,手机终端执行相关的操作,有点类似于远程控制的功能,但是
和远程控制不同的是:这里需要传输文件数据,这种控制是通过应用软件来实现的。
2.设计和实现:
设计的过程中,最原始的设计思路是用socket的同步服务器模型。这种模型的典型特点就是在同一个时刻
只能允许一个连接,这个连接处理完毕后才可以进行下一个连接。服务器的处理流程在一个while死循环中
,这也是最简单最容易实现的模型。但是在设计到一半的时候,流产了,原因想必大家已经可以猜到了,
需求不符合,非功能性需求中要求同时可以连接最多为1000部终端。这种模型无法达到需求。改进模型为
并发模型,首先并发模型有好多种实现方式:多进程并发,在linux中可以进行系统调用fork()就可以
创建一个子线程,子线程从fork()调用开始处,子线程执行之后的代码,调用成功返回子线程的id非零,
不成功返回零。在linux中可以这样写代码:(不是很严谨,欢迎指正)。
。。。
Bind();
listen();
while(1)
{
//接受新的socket
accept();//accept函数返回新的socket
if(fock())
{
。。。//处理接入的socket
}
else
break;
}
。。。
这种情况,暂时不考虑,因为平台为windows server 2003,windows平台的实现方式为进程或者线程
考虑我的开发平台为vs2008,c#,对于线程的类库,有一个threadPool,就是线程池,具体的底层的实现
机制并没有进行仔细的研究,准备以后有时间用反射工具看看了,对于每个连接的socket进入线程池进行
操作,实现的大致代码如下:
public void Start()
{
if (isRun)
{
System.Diagnostics.Debug.WriteLine(ErrorCode.Str_SERVER_IS_RUNING);
//throw new CustomException(ErrorCode.SERVER_IS_RUNING);
return;
}
//初始化socket
svrSock = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
//绑定端口
IPEndPoint iep = new IPEndPoint(IPAddress.Any, port);
try
{
svrSock.Bind(iep);
}
catch (Exception ee)
{
System.Diagnostics.Debug.WriteLine("绑定端口异常,请检查端口是否占用");
if (Notify != null)
Notify("服务启动失败,绑定端口异常\r\n");
CloseSock(svrSock);
return;
}
//开始监听
try
{
svrSock.Listen(5);
}
catch (Exception ee)
{
System.Diagnostics.Debug.WriteLine("主服务端口侦听异常,请检查服务端口侦听");
if (Notify != null)
Notify("服务启动失败,主服务端口侦听异常\r\n");
CloseSock(svrSock);
return;
}
if (Notify != null)
Notify("服务已启动\r\n");
isRun = true;
while (true)
{
Socket sock = null;
try
{
sock = svrSock.Accept();
}
catch (Exception ee)
{
isRun = false;
System.Diagnostics.Debug.WriteLine("监听端口关闭");
CloseSock(svrSock);
CloseSock(sock);
if (Notify != null)
Notify("监听端口关闭\r\n");
break;
}
//启动线程池进行接收数据
ThreadPool.QueueUserWorkItem(new WaitCallback(WorkThread), sock);
}
}
在线程方法中的方法中处理接入的请求。
不论是线程,还是进程,对于服务的模型基本就是这两种了,但是服务器的复杂性远比这要复杂多了,需要保存
客户端的相关信息,处理发送和接受数据,等等。。。
这些现在都不考虑了,因为我题目的主题是实现通用的CS模型,也就是可以复用,这种模型现在已经实现了,并且测试
也都通过了,但是连接的数量并没有1000个,也就是没有进行压力测试。但是可以思考,如果1000个终端同时接入,
那么需要启动1000个线程,这本身就是一种缺陷,因为1000个线程的创建需要很大的代价,更何况windows的机制
限制了线程的个数。同时1000个线程使用完毕就销毁了,现在思考的问题就是是不是有一种方法,创建很少的线程,让他
们当没有接入时阻塞,有连接时就进行处理,处理完毕就在阻塞。
如何处理?
这个问题可以考虑用启动数量有限的线程,然后等待,用事件进行通知线程有接入的请求,但是事件通知时,接入的
socket信息并没有带入到线程中。
对于window的底层机制中,有socket的异步调用方法,进行异步调用。但是这种模型本质上和我刚才的实现没有本质
的区别,继续查找msdn,网页,终于IOCP被查出来了。。。
查出iocp的原理时,仿佛就像男孩对女孩的一见钟情一样,第一眼就确定了,就是她了。。。
通过大量的查找资料,终于明白了原来高性能服务器就是这样做出来的啊。iocp的原理首先做一下简单的介绍:
首先介绍一下进程对io等资源的访问,也就是独占资源的访问,io资源通常包括文件资源等,也就是同一个时间只能由一个
进程或线程访问。socket也是独占资源,当多个线程或进程访问同一个资源时,后访问的会出现阻塞,等到先访问的释放对资源的
占有时,阻塞的进程会被唤醒,执行访问。
iocp的主要机制是充分利用创建的线程池中的线程,避免不停的创建和销毁线程的开销。。。。。。
先写到这儿了,太晚了,要休息了,以后再续。。。。。。
欢迎大家来拍砖。。。。。。