Linux 网络编程 入门-常用函数

网络连接无外乎服务器和客户端两方面的编程。

对于服务器大致的流程是:1---调用socket函数创建套接字

            2---调用bind函数分配IP地址和端口号

            3---调用listsen函数将套接字转为可接受请求状态

            4---调用accept函数受理链接请求

以上四个函数的使用,需要包含头文件   --- #include <sys/socket.h>

完成以上四个步骤,一个完整的能够基础服务器就搭建好了,只需要等待客户端的链接,下面分析一下整个过程中用到的几个函数。

Int socket(int domain,int type,int protocol)

创建网络套接字,成功时返回文件描述符(一个int型的数),失败时返回-1。

什么是网络套接字?----这个不需要关心,其实就是一个打包好的结构。是网络上两个程序双向通讯连接的端点。

A network socket is an endpoint of an inter-process communication across a computer network. Today, most communication between computers is based on the Internet Protocol; therefore most network sockets are Internet sockets.

参数说明:

domain  ----协议族,套接字通信中协议的具体分类。主要用到的有以下几个:

    PF_INET          IPv4互联网协议族

    PF_INET6          IPv6互联网协议族

    PF_LOCAL          本地通信的UNIX协议族

    PF_PACKET          底层套接字的协议族

    PF_IPX             IPX Novell协议族

type   ----套接字类型常用参数有以下:

    SOCK_STREAM  面向连接的套接字。可靠的,按序传递的,基于字节面向连接的套接字。特点:

    1---传输过程中数据不会消失;(拥有独立的内部缓冲区)

    2--按序传输数据;(拥有独立的内部缓冲区)

    3--传输的数据不存在数据边界。(拥有缓冲区,数据可以一次读出也可以分多次读出)

    SOCK_DGRAM  面向消息的套接字。不可靠的,不按序传递的,以字节高速传输的套接字特点:

    1 ---强调快速传输而非传输顺序;

    2---传输的数据可能丢失也可能损毁;

    3---传输的数据有数据边界;

    4---限制每次传输的数据大小。

protocol  ---决定最终采用的协议。大部分情况传递0,除非同一协议族中存在多个数据传输方式相同的协议(有有待理解)

    常用协议有IPPROTO_TCP、IPPROTO_UDP、IPPROTO_STCP、IPPROTO_TIPC等,分别对应TCP传输协议、UDP传输协议、STCP传输协议、TIPC传输协议。type和protocol不可以随意组合,如SOCK_STREAM不可以跟IPPROTO_UDP组合。当第三个参数为0时,会自动选择第二个参数类型对应的默认协议。

Int bind(int sockfd,struct sockaddr *myaddr,socklen_t addrlen);

绑定套接字,给我们创建的套接字分配IP地址和端口号。成功时返回0,失败时返回-1.

参数说明:

sockfd  ---套接字描述符(创建套接字时有产生)

套接字的描述符,一般是定义一个int型的变量,然后作为这个参数,好处就是不要记复杂的数字,我们可以给他一个自己熟悉的名字,以后使用到这个套接字的时候更方便操作。

myaddr  ---sockaddr结构体指针,其中包含了要绑定的地址和端口号。

struct sockaddr {
  unsigned short sa_family; /* address family, AF_xxx */
  char sa_data[14]; /* 14 bytes of protocol address */
 }; 

sa_family :是2字节的地址家族,一般都是“AF_xxx”的形式,它的值包括三种:AF_INET,AF_INET6和AF_UNSPEC。
如果指定AF_INET,那么函数就不能返回任何IPV6相关的地址信息;如果仅指定了AF_INET6,则就不能返回任何IPV4地址信息。
AF_UNSPEC则意味着函数返回的是适用于指定主机名和服务名且适合任何协议族的地址。如果某个主机既有AAAA记录(IPV6)地址,同时又有A记录(IPV4)地址,那么AAAA记录将作为sockaddr_in6结构返回,而A记录则作为sockaddr_in结构返回。
通常用的都是AF_INET。
在通常情况下我们都是使用另一个结构体sockaddr_in来指定绑定的信息,然后再将它强转成sockaddr指针。
struct sockaddr_in {
  short int sin_family; /* Address family */
  unsigned short int sin_port; /* Port number */
  struct in_addr sin_addr; /* Internet address */
  unsigned char sin_zero[8]; /* Same size as struct sockaddr */
};
  sin_family:指代协议族,在socket编程中只能是AF_INET
  sin_port:存储端口号(使用网络字节顺序)
  sin_addr:存储IP地址,使用in_addr这个数据结构
  sin_zero:是为了让sockaddr与sockaddr_in两个数据结构保持大小相同而保留的空字节。
而其中in_addr结构的定义如下:
typedef struct in_addr {
  union {
  struct{ unsigned char s_b1,s_b2, s_b3,s_b4;} S_un_b;
  struct{ unsigned short s_w1, s_w2;} S_un_w;
  unsigned long S_addr;
  } S_un;
  } IN_ADDR;
阐述下in_addr的含义,很显然它是一个存储ip地址的共用体有三种表达方式:
第一种用四个字节来表示IP地址的四个数字;
第二种用两个双字节来表示IP地址;
第三种用一个长整型来表示IP地址。
addrlen  ---myaddr结构体的具体长度,通常使用 sizeof(myaddr)获得。
 

Int listen(int sockfd, int backlog)

将套接字转化成可接受状态。可以接受来自客户端的信号

参数说明:

sockfd  ---用于标识一个已捆绑未连接套接口的描述字。
backlog  ---等待连接队列的最大长度。

Int accept(int sockfd,struct sockaddr *addr,socklen_t *addrlen)

阻塞式等待链接,失败时返回-1.

参数说明:  ---参考bind的说明,注意此处的addrlen是一个指针!!!!!!!!!!!!!!!!

上一篇:【已解决】React项目中按需引入ant-design报错TypeError: injectBabelPlugin is not a function


下一篇:React报错:Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix,