网络编程

bind函数

  1. bind函数可以指定一个端口号,或指定一个IP,或者都指定,或者都不指定。(如果客户端或服务器没有bind一个端口,当调用connect或者listen时,内核就要为响应的套接字选择一个临时端口)
  2. 进程可以把一个特定的IP地址绑定到套接字上,不过这个IP地址必须属于其所在主机的网络接口之一,对于TCP客户,这就为在该套接字上发送的IP数据报指派了源IP地址。对于TCP服务器,这就限定了该套接字只接受那些目的地为这个IP地址的客户连接。TCP客户端通常不把IP地址绑定在它的套接字上,当连接套接字时,内核将根据所用外出网络接口来选择源IP地址,而所用外出接口则取决于到达服务器所需的路径。
  3. 需要注意的是,在调用bind函数时一般不要将端口号置为小于1024的值,因为1到1024是保留端口号,你可以选择大于1024中的任何一个没有被占用的端口号
  4. 绑定通配地址就是告诉系统,要是系统是多宿主机,我们将接受目的地址为任何本地接口的连接。

listen函数

  1. 当socket函数创建一个套接字的时候,它被假设为一个主动套接字,即该套接字将调用connect发起连接的客户套接字。listen函数把一个未连接的套接字转换成一个被动套接字,只是内核应接受指向该套接字的连接请求。CLOSED->LISTEN状态
  2. backlog为最大连接个数。未完成连接队列:每个这样的SYN分节对应其中一项:已由某个客户发出并到达服务器,而服务器正在等待完成相应的TCP三路握手过程,这些套接字处于SYN_RECV状态, 已完成连接队列:每个已完成TCP三路握手的客户端对应其中一项,这些套接字处于ESTABLISHED状态。每当在未连接队列中创建一项时,来自监听套接字的参数就赋值到即将建立的连接中连接的创建机制是完全自动的,无需服务器进程插手。来自客户端的SYN到达时,TCP在未完成连接队列中创建一个新项,然后响应三路握手的第二个分节,直到三路握手的第三个分节到达或者该项超时为止。如果三路握手正常完成,该项就从未完成队列移到已完成队列的队尾。当进程调用accept时,已完成队列中的队头项将返回给进程,如果已连接队列为空,那么就阻塞。
  3. 在三路握手正常完成的前提下(没有丢失分节),为完成连接队列中的任何一项在其中的存留时间就是一个RTT,而RTT取决于特定的客户与服务器。
  4. backlog最好是允许通过命令行选项或者环境变量复写该值。指定一个比内核能够支持的值还要大的backlog可是可接受的,因为内核应该悄然把所指定的偏大值截成自身支持的最大值,而不返回错误。
  5. 当一个SYN到达时,如果队列已满,TCP就忽略该分节,也就是不发送RST。
  6. 在三路握手完成之后,但在服务器调用accept之前要到达的数据应由服务器TCP排队,最大数据量为相应已连接套接字的接受缓冲区大小。
  7. backlog指某个套接字上内核为之排队的最大已完成连接数。

信号的处理方式

  1. 我们可以给指定的信号设置一个信号处理函数,用来捕获信号,有两个信号不能捕获(SIGKILL和SIGSTOP),信号处理函数以发生的信号值作为参数,没有返回值。
  2. 我们可以把某个信号的处置设定为SIG_IGN来忽略它。SIGKILL和SIGSTOP不能被忽略。
  3. 我们可以把某个信号的处置设置为SIG_DFL来启用它的默认处置。

注释

  1. 使用signal时,不同的实现提供不同的信号语义以达成后向兼容,而POSIX则明确规定了调用sigaction函数。所以建议使用sigaction。
  2. POSIX允许我们指定这样一组信号,他们在信号处理函数被调用时阻塞。任何阻塞的信号都不能递交给进程。POSIX 保证被捕获的信号在其信号处理函数运行期间总是阻塞的。
  3. SA_RESTART标志是可选的,如果设置,由相应信号中断的系统调用将由内核自动重启。

POSIX信号的特点

  1. 一旦安装了信号处理函数,它便一直安装着
  2. 在一个信号处理函数运行期间,正在被递交的信号是阻塞的。而且,安装处理函数时再传递给sigaction函数的sa_mask信号集中指定的任何额外信号也被阻塞。
  3. 如果一个信号在被阻塞期间产生了一次或多次,那么该信号被解阻塞之后通常只递交一次,也就是说UNIX信号是不排队的。
  4. 利用sigprocmask函数选择性的阻塞或解阻塞一组信号是可能的。这使得我们可以做到在一段临界区代码执行期间,防止捕获某些信号,以此保护这段代码。

EINTR

        慢系统调用的基本规则是,当阻塞与某个慢系统调用的一个进程捕获某个信号且相应信号处理函数返回时,该系统调用可能返回一个EINTR错误,有些内核自动重启某些被中断的系统调用,不过为了便于移植,我们编写捕获信号的程序时,有必要对慢系统调用返回EINTR有所准备。
        注意:对于accept、read、write、select、open之类的函数而言,以上处理方法合适,不过connect函数返回EINTR时,我们不能再次调用它,否则将立即返回一个错误。当一个connect被一个捕获的信号中断而且不自动重启时,我们必须调用select来等待连接完成。

如果客户端关闭连接的时候,会给服务器发送一个EOF。收到客户的FIN将导致服务器递送一个EOF给标准输入中。
socket的第三个参数表示选择所给定的family和type组合的系统默认值。
linux支持一个新的套接字类型SOCK_PACKET,它支持对数据链路的访问。
客户端调用函数connect之前不一定要调用bind函数,因为如果需要的话,内核会确定源IP地址、并选择一个临时端口作为源端口

并发服务器:同时有大量的客户连接到同一服务器上时用于提供并发性的一种技术。
socket的第三个参数用来选择所给定的family和type组合的系统默认值。
客户在调用函数 connect前不必调用bind函数,因为如果需要的话,内核会确定源IP,并选择一个临时端口作为源端口。

1) 如果TCP客户端没有收到SYN分节的响应,则返回ETIMEDOUT错误
2) 如果对客户的SYN的响应是RST,则表明该服务器主机在我们指定的端口上没有进程在等待与之连接。这是一种硬错误,用户一旦收到RST就返回ECONNREFUSED错误。
a) 产生RST的条件:1.目的地为某端口的SYN到达,但是该端口上没有正在监听的服务器;2.TCP想要取消一个已有连接;3.TCP接受到一个根本不存在的连接上的分节。
3) 如果客户发出的SYN 在中间的某个路由器上引发一个“destination unreadchable”ICMP错误,则认为是一种软错误。客户主机内核保存该消息,并按第一种情况中所述的事件间隔继续发送SYN,若在某个规定的时间(75s)后仍然没有收到响应,则把保存的消息作为EHOSTUNREACH错误返回给进程。

connect函数导致当前套接字从CLOSED状态转移到SYN_SEND状态,若成功则再转移到ESTABLISHED状态。若connect失败则该套接字不再可用,必须关闭,我们不能对这样的套接字调用connect函数,必须close当前套接字描述符并重新调用socket函数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值