1.socket接口(用来创建网络套接字):
int socket(int family, int type, int protocol);
参数:family 指明协议族(IPv4:AF_INET)(IPv6:AF_INET6)
type TCP只支持字节流协议 SOCK_STREAM
protocol 标示某个协议类型常值(TCP设置为0即可)
返回值:成功返回一个非负套接字,失败返回-1
2.connect接口(连接服务器):
int connect(int sockfd, const struct sockaddr *servaddr, socklen_t addrlen);
参数:sockfd 由socket函数返回的套接字描述符
servaddr 套接字地址结构,必须含有服务器ip地址和端口号
addrlen 套接字地址结构长度
返回值:成功返回0,出错返回-1
出错情况分析:
1)TCP客户没有收到SYN分节的确认应答,则errno被设置为ETIMEDOUT。
2)若对客户端SYN分节响应的RST(复位),表明服务器在我们指定端口号上没有进程在等待
与之连接,这是一个硬错误,则errno被设置为ECONNREFUSED。
RST是TCP在发生错误时发送的一个分节。产生RST的三种情况:1)服务器该端口的服务
没有开启。2)TCP取消一个已有连接。3)TCP接收到一个不存在的 连接上的分节。
3)客户端SYN分节在某个路由上引发一个“destination unreachable”(目的地不可达)的ICMP
错误,这是一种软错误。客户端主机内核会保存改消息,然后按照第一 种情况的时间间隔
继续发送SYN分节,若是在规定时间后仍未收到响应,则把保存的消息(ICMP错误)作为
EHOSTUNREACH或者ENETUNREACH错误返回 给进程。
注意:这个函数是一个阻塞函数,发起三次握手,直到连接成功或者失败才会返回。在connect失败后,
我们不能更换服务地址和端口号,再次继续connect,我们必须关闭之前的套接字描述符,然后
再申请新的,然后再connect。
3.bind接口(把一个本地协议地址绑定到一个套接字,本地协议地址是ip地址和端口号的组合):
int bind(int sockfd, const struct sockaddr *myaddr, socklen_t addrlen);
参数:sockfd 由socket函数返回的套接字描述符
myaddr 套接字地址结构,(对于TCP,端口号和ip地址指不指定无所谓,不指定机器会自动分配)
addrlen 套接字地址结构长度
返回值:成功返回0,出错返回-1
4.listen接口(把一个未连接的套接字转换成一个被动套接字,指示内核应该接受指向改套接字的连接请求,
把套接字状态从CLOSED转到LISTEN):
int listen(int sockfd, int backlog);
参数:sockfd 由socket函数返回的套接字描述符
backlog sockfd套接字排队的最大连接个数
返回值:成功返回0,出错返回-1
注意:监听套接字(LISTEN状态套接字)维护两个队列:
未完成连接队列:某个客户端发送SYN分节并送达服务器,而服务器正在等待完成相应的TCP
三路握手过程,这些套接字出于SYN_RCVD状态。
已完成连接队列:已完成TCP三路握手过程的连接,套接字处于ESTABLISHED状态。
TCP为监听套接字维护的两个队列图
5.accept接口(生成与客户端的TCP连接):
int accept(int sockfd, const struct sockaddr *cliaddr, socklen_t addrlen);
参数:sockfd 由socket函数返回的套接字描述符
cliaddr 客户端套接字地址结构
addrlen 套接字地址结构长度
返回值:成功返回非负套接字描述符,出错返回-1
6.close接口(关闭套接字、终止TCP连接):
int close(int sockfd);
参数:sockfd 由socket函数返回的套接字描述符
返回值:成功返回0,出错返回-1