zoukankan      html  css  js  c++  java
  • CS通用模型设计,socket,tcp实现()

    最近,一直在做一个手机为客户端的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的主要机制是充分利用创建的线程池中的线程,避免不停的创建和销毁线程的开销。。。。。。

      先写到这儿了,太晚了,要休息了,以后再续。。。。。。

      欢迎大家来拍砖。。。。。。 


  • 相关阅读:
    Django Model数据访问Making queries
    Tomcat 7源码学习笔记 -5 web app自动reload
    tomcat启动提示server.xml的context节点中不支持source属性警告的解决方法
    javaweb学习总结(三十九)——数据库连接池
    共享文件系统
    高可用+负载均衡 方案
    Java对象克隆(Clone)及Cloneable接口、Serializable接口的深入探讨
    Java对象序列化给分布式计算带来的方便
    JAVABEAN必须继承序列化借口的作用
    keep-alive pipeline区别
  • 原文地址:https://www.cnblogs.com/xingyayang/p/1651174.html
Copyright © 2011-2022 走看看