1.socket(int family, int type, int protocol);
返回:若成功则为非负描述符,若出错则为-1
功能:创建一个未连接的套接字
family指明地址协议族,type指明套接字类型,protocol为某个协议类型常值。
对比AF_XXX和PF_XXX:AF_前缀表示地址族(address family),PF_前缀表示协议族(protocol family),历。史上曾想单个协议族可以支持多个地址族,PF_用来创建套接字,
AF_用于套接字地址结构。但实际上,这样的协议族未曾实现过,头文件中<sys/socket.h>中为给定协议定义的PF_值总是与此协议的AF_值相等。
2.connect(int sockfd, const struct sockaddr *servaddr, socklen_t addrlen);
返回:若成功则为0,若出错则为-1
功能:TCP客服用connect函数来建立与TCP服务器的连接。
指针和指针所指向内容的大小都传递给内核,于是内核知道到需从进程赋值多少数据进来。
返回错误的三种情况:
(1)若TCP客户没有收到SYN分节的响应,返回ETIMEDOUT错误;
(2)对客户的响应是RST,则表明该服务器主机在我们指定的端口没有进程在等待与之连接,返回ECONNREFUSED错误;
产生RST的三个情况:如前所述;TCP想取消一个已有的连接;TCP收到一个根本不存在的连接上的分节。
(3)若客户发出的SYN在中间的某个路由器上引发了一个"destination unreachable"ICMP错误,返回EHOSTUNREACH或ENETUNREACH错误给进程。
注意:每次connect失败后,都必须close当前的套接字描述符并重新调用socket。
3.bind(int sockfd, const struct *myaddr, socklen_t addrlen);
返回:若成功则为0,若出错则为-1
功能:bind函数把一个本地协议地址赋予一个套接字,调用bind可以指定IP地址或者端口,可以两者都指定,也可以都不指定。
(1)端口号:服务器在启动的时捆绑它们的端口,如果一个客户端或服务器未曾调用bind捆绑一个端口,当调用connect或listen时内核就要为套接字选择一个临时端口,
然而这对于TCP服务器来说极为罕见,且bind不返回所选择的值,必须调用getsockname来返回协议地址。
(2)地址:进程可以把一个特定的IP地址捆绑到它的套接字上,不过这个IP地址必须属于其所在主机的网络接口之一;若TCP客户不捆绑IP地址到套接字上,内核将根据外出网络接口
选择源IP地址;若TCP服务器没有捆绑地址到套接字上,内核就把客户发送的SYN的目的地址作为服务器的源IP地址。
4.listen(int sockfd, int backlog);
返回:若成功则为0,若出错则为-1
功能:listen函数仅由TCP服务器调用,主要完成两件事:
(1)当socket函数创建一个套接字时默认为主动套接字,即一个客户将调用connect发起连接的客户套接字,listen函数把这个未连接的套接字转换成一个被动套接字,指示内核
应接受指向该套接字的连接请求;
(2)规定了内核应该为这个套接字排队的最大连接个数。
内核为任何一个监听套接字维护两个队列:未完成连接队列(incomplete connection queue)和已完成连接队列(completed connection queue),listen函数的backlog参数曾经
被规定为这两个队列总和的最大值。
(1)未完成连接队列:队中每一项对应一个由客户端发出并到达服务器的SYN分节,而服务器正在等待完成相应的TCP三路握手过程。
(2)已完成连接队列:队中每一项对应一个已完成TCP三路握过程的客户,当调用accept时,已完成连接队列的对头项将返回给进程。
5.accept(int sockfd, struct sockaddr *cliaddr, socklen_t *addrlen);
返回:若成功则为非负描述符,若出错则为-1
功能:服务器用于从已完成连接队列队头返回下一个已完成连接,如果已完成队列为空,那么进程被投入睡眠(假定套接字为默认的阻塞方式)。
参数cliaddr和addrlen用于返回已连接的对端进程(客户)的协议地址,addrlen是一个值-结果参数(Value-Result Argument)。
6.close(int sockfd);
返回:若成功则为0,若出错则为-1
功能:把该套接字标记成已关闭,然后立即返回到调用进程。