TCP连接的建立--connect函数

走远了吗. 提交于 2020-01-24 21:38:46

众所周知,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表示连接本机)
在这里插入图片描述

  1. 当客户发出报文但是没有收到回应的时候,比如三次握手中发送SYN分节,但是由于一些原因服务端没有收到,这个时候在等待6s后客户端重发,一直到75s后仍然没有相应,则会返回错误,并设置errno为ETIMEDOUT
    我们用客户端连接一个不存在局域网中的网络作为测试:
    在这里插入图片描述
    从图中可以看出由于重复发送SYN没有收到会用,经过一段时间后返回一个ETIMEDOUT错误
  2. 如果客户发出SYN后对端传过来了RST,说明在我们指定的ip和端口处没有正在处于listen的服务器,或者说对端服务器没有开启,则此时会返回次所,并设置errno为ECONNREFUSED
    发送RST的原因有三种:
    (1)对端没有服务器处于监听状态
    (2)对端想要断开连接
    (3)第三次握手丢失,客户在发送数据的时候,服务端认为是非法,向客户端发送RST
    这里我们关闭服务器,然后只用客户端进行连接
    在这里插入图片描述
    从图中可以看出,由于服务器关闭了,在收到SYN后会认为是非法连接,返回RST,内核会返回错误,并设置errno为ECONNREFUSED。
  3. 如果对端不可达,(返回ICMP错误),即无法在路由转发表中找到该地址,则客户端会持续发送SYN,直到75s后返回错误,并设置errno为EHOSTUNREACH或者ENETUNREACH
    这种情况试了几次都是timeout,没有找到不存在的网络地址。。

最后说一下用于connect的套接字在连接失败之后必须先close,然后才能重新用于connect。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!