众所周知,TCP是面向连接的协议,我在前面的文章中也有写到过三次握手的过程
有兴趣的可以看一看tcp三次握手和四次挥手
今天就来看一看socket编程中关于三次握手建立连接的函数–connect
我们在这里还是把建立连接的一方抽象为客户端,接收连接的抽象成服务端
函数原型
#include <sys/socket.h>
int connect(int sockfd,const struct sockaddr *servaddr,socklen_t addrlen);
- sockfd:socket函数返回的套接字描述符,用来通信。
- servaddr:指向服务端套接字地址结构的指针,为了实现通用性,将其转换成sockaddr*的类型
- addrlen:表示套接字地址结构的大小
- 成功返回0,失败返回-1,并设置errno
分析函数失败的几种原因
在分析演示之前先使用ifconfig查看我当前电脑的ip地址
然后我正常连接是可以正常进行通信的(服务器是简单的回射服务器,127.0表示连接本机)
- 当客户发出报文但是没有收到回应的时候,比如三次握手中发送SYN分节,但是由于一些原因服务端没有收到,这个时候在等待6s后客户端重发,一直到75s后仍然没有相应,则会返回错误,并设置errno为ETIMEDOUT。
我们用客户端连接一个不存在局域网中的网络作为测试:
从图中可以看出由于重复发送SYN没有收到会用,经过一段时间后返回一个ETIMEDOUT错误 - 如果客户发出SYN后对端传过来了RST,说明在我们指定的ip和端口处没有正在处于listen的服务器,或者说对端服务器没有开启,则此时会返回次所,并设置errno为ECONNREFUSED。
发送RST的原因有三种:
(1)对端没有服务器处于监听状态
(2)对端想要断开连接
(3)第三次握手丢失,客户在发送数据的时候,服务端认为是非法,向客户端发送RST
这里我们关闭服务器,然后只用客户端进行连接
从图中可以看出,由于服务器关闭了,在收到SYN后会认为是非法连接,返回RST,内核会返回错误,并设置errno为ECONNREFUSED。 - 如果对端不可达,(返回ICMP错误),即无法在路由转发表中找到该地址,则客户端会持续发送SYN,直到75s后返回错误,并设置errno为EHOSTUNREACH或者ENETUNREACH。
这种情况试了几次都是timeout,没有找到不存在的网络地址。。
最后说一下用于connect的套接字在连接失败之后必须先close,然后才能重新用于connect。
来源:CSDN
作者:程序猿养成ing
链接:https://blog.csdn.net/weixin_44623601/article/details/103780716