博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
什么是套接口?
阅读量:4176 次
发布时间:2019-05-26

本文共 2681 字,大约阅读时间需要 8 分钟。

目录


SYN:同步序列编号(Synchronize Sequence Numbers),是TCP/IP建立连接时使用的握手信号。

ACK:确认字符(Acknowledge character),在数据通信中,接收站发给发送站的一种传输类。表示发来的数据已确认接收无误。

       在客户机和之间建立正常的TCP网络连接时,客户机首先发出一个SYN消息,服务器使用SYN+ACK应答表示接收到了这个消息,最后客户机再以消息响应。这样在客户机和服务器之间才能建立起可靠的TCP连接,数据才可以在客户机和之间传递。

什么是套接口?socket、套接口、套接口描述符之间的关系

  UNP 的译者在 p6 中的译注中提到:socket 一词应该译成“套接口”,理由如下:首先,作为网络编程 API 之一的套接口(sockets.注意这种用法总是采用复数形式,例如 sockets API、sockets library)跟 XTI 一样,是应用层到传输层或其他协议层的访问接口。其次,具体使用的套接口时与 unix 管道的某一端类似的东西,我们既可以往这个“口”写数据,也可以从这个“口”读取数据。最后,套接口函数使用套接口描述字访问具体的套接口,如果把套接口描述字的简称 socketfd 译成“套接字”倒比较合适。从这个意义上来讲,一个套接口可以对应多个套接字,因为 unix 的描述字既可以复制,也可以继承,反过来,一个套接字对应且只对应一个套接口。

如何创建套接口?

  unix下通过 socket 函数创建套接口,该函数原型是:

  int socket(int family, int type, int protocol)。

  其中,family 参数指明协议族,它是 AF_INET(IPv4 协议)、AF_INET6(IPv6)协议、AF_LOCAL()、AF_ROUTE(路由套接口)、AF_KEY(密钥套接口)中的一种。

  其中, type 指明套接口类型,它是SOCK_STREAM(字节流套接口)、SOCK_DGRAM(数据报套接口)、SOCK_SEQPACKET(有序分组套接口)、SOCK_RAW(原始套接口)中的一个。

  其中,protocol 是 IPPROTO_TCP( TCP 协议)、IPPROTO_UDP( UDP 协议)、IPPROTO_SCTP(SCTP协议)中的一种。

  如果创建成功返回套接口描述符,简称套接字

套接口用来做什么?

   在客户端:通过 connet() 用来与服务器建立连接。connet() 函数原型如下:

  int connec(int sockfd, const struct socktaddr *servaddr, socklen_t addrlen); 

  其中,sockfd 就是套接口描述符(用来描述套接口)。

  其中,servaddr 是套接口地址结构,这个结构用来指定 connect() 要连接的服务器的 IP 和 端口号。

  其中,addrlen 时套接口地址结构的大小。

  由于 connect() 函数要在客户端与服务器端建立连接,所以在调用 connect() 的时候会激发三次握手:1.主动请求连接方向被动请求连接方发送一个 SYN 分节,此时主动方处于 SYN_SENT 状态,如果被动方收到 SYN 分节,并返回一个 ACK 和 一个自己的 SYN,此时被动方处于SYN_RCVD 状态。调用 connect() 的主动方接受到被动方回应的 ACK 后,connect() 返回 0(表示成功),否则回返回 -1(出错)。connect() 成功返回后,主动方处于 ESTABLISHED 状态,表示连接已经建立。并向被动方发送一个 ACK(用来回应被动方发送的 SYN 分节)。

  在服务器端:在服务器端稍微复杂一点点,要比客户端多两个步骤:

  1、用 bind() 函数将一个本地协议地址赋予一个套接口。对于网际地址时 32 为的 IPV4地址或 128 位的 IPV6 地址与 16 位的 TCP 或 UDP 端口号的组合。bind() 函数原型如下:

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

  bind() 函数的原型和 connect() 一样,但作用还是有差别的。connect() 是将 sockfd 与套接口地址结构对应的服务器建立连接,而 bind() 是将 sockfd 与本地套接口地址结构进行绑定。

  2、调用 listen() 函数将套接口变成监听套接口,listen() 原型如下:

  int listen(int sockfd, int backlog);

  其作用有两个:a.将一个未连接的套接口转换成一个被动套接口,只是内核应该接受指向该套接口的的连接请求。并使套接口从 closed 状态转换到 LISTEN 状态。

         b.listen() 的第二个参数规定了内核应该为相应套接口排队的最大连接个数。

  3、调用 accept() 函数在监听套接口(由listen()转化的套接口描述符)接受新连接的到达,如果没有新连接到达那么进程就投入睡眠(假设套接口为缺省的阻塞方式)。上面我说过,客户端是通过 connect() 来建立连接的,在客户端收到服务器端的 ACK时,connect() 函数返回,并且发送一个 ACK,当服务器端接受到这个 ACK 时,此时三次握手完成。连接建立完成,新连接到达,此时,服务器端的监听套接口转换成 ESTABLISHED 状态,accept() 成功返回。

  accept() 函数原型如下:int accept(int sockfd, struct sockaddr *cliaddr, socklen_t *addrlen);

  其中, sockfd 时监听套接口,cliaddr 是已连接的对端进程(客户)的协议地址。addrlen 是值-结果参数,是内存存在该套接口地址结构(cliaddr)的确切字节数。

  accept() 返回非负描述符,我们称其为已连接套接口描述符。一定要区别监听套接口描述符和已连接套接口描述符,一般来说服务器在其生命周期内只创建一个监听套接口描述符,而内核为每个由服务器进程接受的客户连接创建一个已连接套接口。

转载地址:http://zptai.baihongyu.com/

你可能感兴趣的文章
JVM 的垃圾回收器
查看>>
Mybatis的缓存
查看>>
@validated注解异常返回JSON值
查看>>
@JsonFormat注解使用
查看>>
Spring boot集成jxls实现导入功能
查看>>
Spring boot读取配置的方式(指定配置文件)
查看>>
Spring Boot切换不同环境配置
查看>>
Spring cloud之Ribbon搭建
查看>>
TreeMap 与 HashMap 的区别
查看>>
初识CAS
查看>>
Fork/Join 框架
查看>>
服务雪崩效应
查看>>
策略模式实例
查看>>
PostgreSQL数据库管理 第八章日常运维
查看>>
PostgreSQL数据库管理第十章Repmgr
查看>>
Linux shell正则表达式-sed-awk-grep应用
查看>>
linux系统管理—第五章Linux-bashshell
查看>>
PostgreSQL数据库管理 第二章体系结构
查看>>
PostgreSQL数据库管理 第三章实例管理与管理工具
查看>>
PostgreSQL数据库管理第七章流复制
查看>>