zoukankan      html  css  js  c++  java
  • linux execl()函数 关于execl()函数族的用法不在赘述,

    linux execl()函数 关于execl()函数族的用法不在赘述,

    1.TCP和UDP协议

        共同点:同为传输层协议

        不同点: TCP:有连接,可靠

            UPD 无连接,不保证可靠

        TCP(即传输控制协议):

           是一种面向连接的传输层协议,它是能提供高可靠性通信(即,数据无误,数据无丢失,数据无失序、数据无重复到达的通信)

           适用情况:

              适合于对传输质量要求较高,以及传输大量数据的通信。

              在需要可靠数据传输的场合,通常使用TCP协议

              QQ等即时通讯软件的用户登录账户管理相关的功能通常采用TCP协议

        UDP(User Datagram Protocol)用户数据报协议

            是不可靠的无连接协议。在数据发送前,因为不需要进行连接,所以可以进行高效率的数据传输。

            使用情况:

            发送小尺寸数据(如对DNS服务器进行IP地址查询时)

            在接收到数据,给出应答较困难的网络中使用UDP。(如:无线网络)      

            适合于广播、组播式通信中。

            MSN/QQ/Skype等即时通讯软件的点对点文本通讯以及音视频通讯通常采用UDP协议

            流媒体、VOD/VoIP/IPTV等网络多媒体服务中通常采用UDP方式进行实时数据传输。

    2.socket

        是一个编程接口

        是一种特殊的文件描述符(everything in Unix is a file) 

        并不仅限于TCP/IP协议

        面向连接(Transmission Control Protocol  Protocol    -TCP/IP)

        无连接(User Datagram Protocol  -UDP 和 Inter-network Packet Exchange  -IPX)

        

        Socket类型:

          流式套接字(SOCK_STREAM)

            提供了一个面向连接、可靠的数据传输服务,数据无差错、无重复的发送且按发送顺序接收。内设置流量控制,避免数据流淹没慢的接收方。数据被看做是字节流,无长度限制。(TCP)

          数据报套接字(SOCK_DGRAM)

            提供无连接服务。数据包以独立数据包的形式被发送,不提供无差错保证,数据可能丢失或重复,顺序发送,可能乱序接收(UDP)

          原始套接字(SOCK_RAM)

            可以对较低层次协议如IP、ICMP直接访问。(如  Ping )

    3.IP地址

       IP地址是Internet 中主机的标识

       IP地址为32位(IPv4)或者128位(IPv6)

       ipv4表示形式:点分十进制,例如:192.168.1.123

       IP地址分类(根据ipv4前八位来区分):

        A类   0000 0000  - 0111 1111   0.x.x.x   -  127.x.x.x

        B类   1000 0000  - 1011 1111   128.x.x.x - 191.x.x.x

        C类   1100 0000 -  1101  1111   192.x.x.x  -  223.x.x.x

        D类    1110 0000  - 1110  1111   224.x.x.x  -  239.x.x.x   组播地址

        E类     1111 0000  -  1111  1111  240.x.x.x  -  255.x.x.x 保留测试

        192.168.x.x  属于局域网Ip地址,可以砸任意一个ip地址下使用路由器分配地址

          以192.168.1.x为例:

            192.168.1.255  广播地址

            192.168.1.0  表示网络号

            192.168.1.1  表示网关

          127.x.x.x   属于本机地址

        子网掩码:可以用于得到当前最大的主机连接数

          A类:255.0.0.0  0~24

          B类:255.255.0.0  2~16

          C类:255.255.255.0  2~8

        #include<arpa/inet.h>

         将点分十进制ip地址转化为网络字节序的整形数据

         in_addr_t    inet_addr(const char *cp);

         将网络字节序的整形数据转化为点分十进制ip地址

          char * inet_ntoa(struct in_addr in);

          例子:

            inet_addr("192.168.1.123");

     4.端口号

       为了区分一台主机接收到的数据包应该转交给哪个进程来进行处理,使用端口号来区别

       TCP端口号与UDP端口号独立

       端口号一般由IANA(Internet Assigned Numbers Authority) 管理

       众所周知端口:1~1023(1~255之间为众所周知端口,256~1023端口通常由UNIX系统占用)

       已登记端口:1024~49151
       动态或私有端口:49152~65535

       使用 vi /etc/services 可以查看已经使用的端口号

       一般使用 5555、6666、7777、8888、9999、10001、10000

    5.字节序

      不同类型CPU的主机中,内存存储多字节整数序列有两种方法,称为主机字节序(HBO):
      小端序(little-endian) 
        低序字节存储在低地址,将低字节存储在起始地址,称为“Little-Endian”字节序,Intel、AMD等采用的是这种方式;

      大端序(big-endian)
        高序字节存储在低地址,将高字节存储在起始地址,称为“Big-Endian”字节序,由ARM、Motorola等所采用

        如何测试主机字节序:
          方法1:使用指针
          方法2:使用file命令, file a.out,其中LSB的L为小端存储
          方法3:使用共用体

      网络字节序:大端存储

        主机字节序和网络字节序转换接口:

          #include <arpa/inet.h>

          将主机字节序转化为网络字节序
          uint32_t htonl(uint32_t hostlong);
          uint16_t htons(uint16_t hostshort);

          将网络字节序转化为主机字节序
          uint32_t ntohl(uint32_t netlong);
          uint16_t ntohs(uint16_t netshort);

          例子:
          htons(9999);

    流程
       服务器:server
         创建套接字 socket( )
        填充服务器网络信息结构体 sockaddr_in
        将套接字与服务器网络信息结构体绑定 bind( )
        将套接字设置为被动监听状态 listen( )
        阻塞等待客户端的连接请求 accept( )
        进行通信 recv( )/send( ) 或 read( )/write( )

       客户端:client
        创建套接字 socket( )
        填充服务器网络信息结构体 sockaddr_in
        发送客户端的连接请求 connect( )
        进行通信 recv( )/send( ) 或 read( )/write( )

     

    1,io模型:

      阻塞io、非阻塞io、io多路复用,信号驱动io。

    阻塞Io与非阻塞io的转换,可用fcntl()函数

      #include<unistd.h>

      #include<fcntl.h> 

     int fcntl(int fd,int cmd,...);

    2,io多路复用

      在应用程序中同时处理多路输入输出流

      若采用阻塞模式,将得不到预期的目的

       若采用非阻塞模式,对多个输入进行轮询,则浪费CPU资源

       若设置多个进程,分别处理一条数据通路,将新产生进程间的同步与通信问题

        使得程序变得过于复杂。

      这时,比较好的方法是使用IO多路复用,其基本思想是:

        先构造一张有关描述符的表,然后调用一个函数。

        当这些文件描述符中的一个或多个已准备好进行IO函数时,函数才返回

        函数返回时,高诉进程哪个描述符已经就绪,可以进行IO操作。

      使用IO多路复用时,主要用到以下函数(LINUX)

      int select(int nfds,fd_set *readfds,fd_set *writefds,fd_set * exceptfds,struct timeval * timeout);

      void FD_ZERO(fd_set *set);

      void FD_SET(int fd,fd_set *set);

      void FD_CLR(int fd,fd_set *set);

      int FD_ISSET(int fd,fd_set *set);

    莫做伸手党。

    3,实现TCP并发服务器

      方法一:通过使用父子进程实现tcp并发服务器

      方法二:使用select函数实现tcp并发服务器

    法一:

      socket();

      sockaddr_in;

      bind();

      listen();

      while(1)

      {

      accept();

      pid = fork();

      if(pid > 0){}父进程负责连接

      else if(pid == 0){

      while(1)

      {

      recv()/send();

      }

      }

      }

      这里有个难点:一个客户端退出后,如何避免对应的“服务器”进程,编程僵尸进程?

            解决办法是:采用信号,来回收客户端对应“服务器的资源”。

      法二:笔者也在琢磨。。。。。。

     

    关于execl()函数族的用法不在赘述。下面说下作者在使用该函数时所犯的错误:

    作者想通过使用execl()函数在子进程中调用其他函数,起初楼主是 这样用的:

    if((a = execl("~/linux_io/3/3.2/3.2.1/2/hello","hello",NULL)) < 0)

    {

      perror("error:");

    }

    结果一直提示找不到文件,最后发现它不识别~号。。。。。。。。

    改为:/home/linux/linux_io/3/3.2/3.2.1/2/hello 才对

  • 相关阅读:
    JavaFx初探
    TraceView总结
    sprintf,你知道多少?
    C/C++:多个.cpp文件包括同一个.h头文件定义方法
    Android中Preference的使用以及监听事件分析
    Android系统默认Home应用程序(Launcher)的启动过程源码分析
    升级、备份红帽PaaS openshift 上的 wordpress
    几种开源分词工具的比較
    设计模式奠基石——UML关系转化为代码
    Windows 7系统安装MySQL5.5.21图解
  • 原文地址:https://www.cnblogs.com/xinxihua/p/12563848.html
Copyright © 2011-2022 走看看