zoukankan      html  css  js  c++  java
  • 服务器的基本问题避免

    TCP/IP协议的 11 中状态;

    开发服务器中避免出现的问题:

    一。服务器中表面出现僵尸进程:(SIGCHLD信号的处理)

    1. 多进程服务器; 一个管理进程, 当客户端链接时, 起一个子进程与客户端进程通信;

    2. 客户端:普通客户端程序, 与服务器之间保持长链接。

    3.问题:

      此时设计到一个问题,当起 n 个客户端连接服务器时;服务器会产生 n 个子线程,用于各客户端通信,此时,加入一个客户端主动关闭链接,

      服务器应该关掉它对应的子进程,并对这个子进程进行回收,防止产生僵尸进程。

      ① 注册信号,当客户端主动断开连接, 服务器子进程会退出, 此时会向父进程,发送 SIGCHID  信号;父进程注册信号处理函数; signal(SIGCHID, func_data);

      func_data()   {   wait(NULL); }    (伪代码, 该函数的格式不对)。

      会调用该信号函数回收子进程;

      ②加入:多个链接客户端同时关闭连接, 此时会同时向服务器发送:FIN标识位,服务器多个子进程同时退出, 并同时向主进程 发出SIGCHID信号; 这时,上面的

      程序设计就出现问题。 因为: SIGCHID 信号是不可靠信号,当多个信号同时向父进程发送时, 服务器主进程可能回处理 1 个, 或多个 < n, 或者n个(理想状态),那么就会有很大可能产生僵尸进程。  为了避免这种情况的发生; 上面的信号注册函数, 就应该写成这样, 才可以避免该问题。

      func_data()   { int mypid = 0;  while( ( mypid = waitpid(-1, NULL, WNOHANG ) ) > 0 { ; (此处循环可以为空)} } 。

     二。通信中出现SIGPIPE信号:(SIGPIPE信号的处理和该信号出现的时机)

      1. 在网路通信中, 因为套接字为 全双工通信;

       当 server 关闭 一个套接字后,client 继续向该套接字发送消息, 按照 TCP 协议规定, client 会收到一个RST响应, client再用该套接字向 server发送数据时,

      会收到SIGPIPE信号, 该信号的默认处理方式:终端当前进程;如果不对该信号进行处理,会造成当前的程序不稳定, 出现上述情况时,会使client 退出。

      (server端亦然);

      2.  为避免程序退出, 就需要对该信号进行处理, 两种方式: 1. 忽略该信号 signal(SIGPIPE, SIG_IGN); 2.捕捉该信号signal(SIGPIPE, 捕捉函数);

      3.对于产生信号,我们可以在产生信号前利用方法 signal(int signum, sighandler_t handler) 设置信号的处理。如果没有调用此方法,系统就会调用

      默认处理方法:中止程序,显示提示信息(就是我们经常遇到的问题)。我们可以调用系统的处理方法,也可以自定义处理方法。 

      系统里边定义了三种处理方法: 
      (1)SIG_DFL信号专用的默认动作:
        (a)如果默认动作是暂停线程,则该线程的执行被暂时挂起。当线程暂停期间,发送给线程的任何附加信号都不交付,直到该线程开始执行,但是SIGKILL除外。
        (b)把挂起信号的信号动作设置成SIG_DFL,且其默认动作是忽略信号 (SIGCHLD)。
      (2)SIG_IGN忽略信号
        (a)该信号的交付对线程没有影响
        (b)系统不允许把SIGKILL或SIGTOP信号的动作设置为SIG_DFL
      (3)SIG_ERR   

      项目中我调用了signal(SIGPIPESIG_IGN), 这样产生  SIGPIPE 信号时就不会中止程序,直接把这个信号忽略掉。

    三。close与shutdown的区别:(调用方式产生的不同效果,以及他们俩的实现基本原理)

      close() 与shutdown() 关闭套接字的区别:

      1.close(): 采用 引用计数技术;只有当关闭的套接字: 基数为0时, TCP协议 才会向对端发送 FIN 标识符, 表示该套接字关闭;

      2.shutdown(): 只要调该函数关闭套接字: 就会向对端发送 FIN 标识符, 表示 该套接字关闭;

        1.该函数的3种关闭方式: 

              1.SHUT_RD:值为0,关闭连接的读这一半。

              2.SHUT_WR:值为1,关闭连接的写这一半。

              3.SHUT_RDWR:值为2,连接的读和写都关闭。

      3.close与shutdown的区别主要表现在:

             close函数会关闭套接字ID,如果有其他的进程共享着这个套接字,那么它仍然是打开的,这个连接仍然可以用来读和写,并且有时候这是非常重要的 ,

      特别是对于多进程并发服务器来说。

             而shutdown会切断进程共享的套接字的所有连接,不管这个套接字的引用计数是否为零,那些试图读得进程将会接收到EOF标识,那些试图写的进程

      将会检测到SIGPIPE信号,同时可利用shutdown的第二个参数选择断连的方式。

    四。长链接、短链接

      1.长链接: 表示一直链接, 不断开;

        while(1){

          write();

          read();

        }close();

      2.短链接:发送完数据后,就断开。

         {    //该数据一轮 收发完后, 立即断开。

          write();

          read();

          close();   

        }

  • 相关阅读:
    HTTP深入浅出 http请求
    ASP.NET MVC 4
    ASP.NET MVC 4 (十三) 基于表单的身份验证
    ASP.NET MVC 4 (十二) Web API
    ASP.NET MVC 4 (十一) Bundles和显示模式
    ASP.NET MVC 4 (十) 模型验证
    ASP.NET MVC 4 (九) 模型绑定
    ASP.NET MVC 4 (八) URL链接和Ajax帮助函数
    ASP.NET MVC 4 (七) 模板帮助函数
    ASP.NET MVC 4 (六) 帮助函数
  • 原文地址:https://www.cnblogs.com/yyx1-1/p/6241863.html
Copyright © 2011-2022 走看看