unp-cha4 summary

来源:互联网 发布:知进退明得失谁说的 编辑:程序博客网 时间:2024/06/09 23:25

  本章详细描述了socket函数的用法,参数说明等基本知识。下面我们一一介绍:

  首先是函数

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

                       Returns: non-negative descriptor if OK, -1 on error

  其中family指定了协议族,有以下几个常量:AF_INET是IPv4的协议族,AF_INET6是IPv6的协议族,AF_LOCAL是unix的协议族(domain protocol)还有AF_ROUTE和AF_KEY。

  type是以下常量之一:SOCK_STREAM,SOCK_DGRAM,SOCK_SEQPACKET和SOCK_RAW。

  protocol必须指定为IPPROTO_TCP,IPPROTO_UDP和IPPROTO_SCTP之一,或者为0让系统自动选择有family和type的组合而定。

  下面一个函数是

 

int connect(int sockfd, const struct sockaddr *servaddr, socklen_t addrlen);

Returns: 0 if OK, -1 on error

其中sockfd是由函数socket返回的值。就TCP socket来说,connect初始化“三次握手”过程,连接过程中可能有以下几种错误发生:

  • 如果client端没有收到SYN段,那么发生错误并返回ETIMEDOUT。
  • 如果客户端收到Server端是RST(reset)的话,说明server端并没有连接可用,返回ECONNREFUSED
  • 如果客户端收到ICMP"destination unreachable"则返回EHOSTUNREACH o或者ENETUNREACH

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

Returns: 0 if OK,-1 on error

此函数分配一个local address给socket,根据协议族是ipv4还是ipv6而定,同时还分配一个16位的端口号。此函数一个常见的错误是“address already in use”。

int listen (int sockfd, int backlog);

Returns: 0 if OK, -1 on error

listen函数有两个功能:

  • 当调用socket函数的时候创建了一个可用的socket,次数客户端可能发起一个连接,系统通过listen函数把未连接的socket转变为pasitive的socket,表示内核应该接受这个连接,同时把socket的CLOSED状态转换为LISTEN状态。
  • 而第二个功能是指明内核为这个socket排队的最大数目,包括已经完成three-way和未完成的,这里backlog有一个历史遗留的问题,但可以通过环境变量来改变数值。因为之前定的最大是5显然不能应付目前大型服务器的连接数。 

int accept (int sockfd, struct sockaddr *cliaddr, socklen_t *addrlen);

Returns: non-negative descriptor if OK, -1 on error

TCP server从上面提到的backlog的队列中调用accept去接受完成三次握手的socket连接,如果队列为空,则进程sleep。如果函数成功调用,则返回一个全新的描述符,描述和TCP client的连接。

pid_t fork(void);

Returns: 0 in child, process ID of child in parent, -1 on error

最后是一个fork函数,通过fork函数来创建一个子进程来处理每个client的连接。

原创粉丝点击