linux高性能服务器编程 (五) --Linux网络编程基础api

第五章 Linux网络编程基础api

  1、主机字节序和网络字节序

    字节序是指整数在内存中保存的顺序。字节序分为大端字节序、小端字节序。

    端字节序:一个整数的高位字节数据存放在内存的低地址处。低位字节存储在内存的高地址处。称为网络字节序

    端字节序:指整数的高位字节序存储在内存的高地址处低位字节则存储在内存的低地址处。称为主机字节序

  

  现代的PC大多数采用小端字节序。当两台使用不同字节序的主机之间进行数据传递时,要判断对方发送过来的数据是否满足当前机器的字节序,如果不满足,则进行数据的转换流程,然后在进行数据储存。因为linux提供了一些函数方法进行格式化。已保证数据能够正常存储。四个函数如下:

  unsigned long int htonl  (从主机字节序转 换到 网络字节序)

  unsigned short int htons (从主机字节序转 换到 网络字节序)

  unsigned long int ntohl (从网络字节序 转到 主机字节序)

  unsigned short int ntohs (从网络字节序 转到 主机字节序)

  2、通用 socket 地址

    在socket网络编程接口中,表示 socket 地址的结构体是 sockaddr 。地址族和协议族的的关系如图:地址族(AF*)协议族(PF*)

  

  其实地址族和协议族都是一样的,值也一样,只是用来识别不同的协议。因为unix有两种风格系统,BSD系统和POSIX系统,对于BSD系统,一直用AF*协议,对于POSIX一直用PF*协议。所以Linux为了兼容两个风格都支持了。

  3、socket

    创建socket :  int socket ( int domain, int type, int protocol);

      说明:创建socket描述符,其实socket也就是一个特殊文件。linux所有东西都是文件。

      参数:

      domain:就是协议族,到时的TCP/IP协议还是UDP协议等。对于TCP/IP协议参数就如上图。

      type: 指定socket服务类型。主要有 SOCK_STREAM服务(流服务,tcp/ip协议会使用这个)SOCK_UGRAM(数据报服务,udp协议会使用这个) 

      protocol: 指定协议,默认是0使用type指定的默认协议。

    命名socket:   int bind (int sockfd const struct sockaddr* my_addr, socklen_t addrlen);

      说明:创建socket后需要给他指定一个地址族,将一个socket与socket地址绑定成为socket命名。

      参数:

      sockfd: 就是创建就的socket,bind()就是将这个socket绑定一个名字

      addr:一个const struct sockaddr*指针,指向要绑定给sockfd的协议地址。

      addrlen:对应的是地址的长度。

      通常服务器在启动的时候会创建一个socket并且给他绑定一个地址(ip+端口号)用于提供服务,客户端就可以通过他来连接服务器。而客户端就不需要指定是哪一个地址。系统会在 客户端connect()的时候自动分配一个端口号+ip地址给他。这就是通常服务器在listen之前会bind()。

      接受连接:      int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

      参数:

      sockfd:就是指被监听的socket

      addr:获取被接受连接的远端socket地址。

        addrlen: 对应的是地址的长度。

    监听socket:   int listen (int sockfd, int backlog);

      说明:socket被命名之后还不能马上接受客户连接。需要创建一个监听对垒存放待处理的客户连接。

      参数:

      sockfd:就是指被监听的socket

      backlog:就是监听队列的最大长度      

    发起连接:    int connect (int sockfd, const struct sockaddr * serv_addr, socklen_t addrlen);

           int read() int write() 进行读写

    关闭连接:    int close( int fd);

      当连接结束时,我们调用close将其关闭,但是close并不总是关闭连接,而是将这个文件描述符的引用计数减1,只有当这个文件描述符的引用计数为0时才会真正关闭。在多进程程序中,一次fork就会使得父进程中打开的文件描述符引用计数加1,所以这种情况下我们就应该对父子进程中的文件描述符都执行一次close。如果要立即终止连接,就可以使用下面的shutdown函数,参数howto的取值分别为SHUT_RD、SHUT_WR和SHUT_RDWR。

  

posted @ 2019-07-08 14:44  清零者  阅读(613)  评论(0编辑  收藏  举报