尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

深入理解socket接口

深入理解socket接口 connect函数函数做了什么事情 传入套接字电话机、服务器IP和端口对方的号码 就是客户端用来主动拨打服务器“电话”的函数 客户端在调用connect前不必调用bind。这就像你打电话时不需要提前告诉电信局“我要用这个号码打出去”操作系统内核会自动帮你选一个空闲的临时端口源端口并自动填上你这台电脑的IP地址源IP。内部发生了什么 (三次握手的触发) 这个函数是“同步阻塞”的——它会一直卡在这里干等直到握手彻底成功或者确认彻底失败才会把结果返回给你。三大碰壁场景情况一服务器“死机”或“网络不通”—— 错误码 ETIMEDOUT超时 发生原因客户端发出的连接请求SYN包石沉大海服务器根本没给任何回应。 底层行为内核不死心会像“催命电话”一样重传。原文提到BSD系统会隔6秒发一次再等24秒发一次总计坚持75秒。 结果实在联系不上放弃返回“连接超时”。 生活类比你打电话给某人那边一直没人接也没挂断你等了整整一分钟最后听到“您拨打的电话无人接听”。情况二服务器“没开这门业务”—— 错误码 ECONNREFUSED连接拒绝 发生原因你的请求SYN成功送到了服务器但服务器发现你指定的“端口号”上没有正在监听的程序比如服务进程没启动。 底层行为服务器立即发回一个 RST复位分节相当于直接“挂断并骂回来”。 结果这是一种硬错误硬伤connect 瞬间返回失败毫不拖延。 生活类比你拨打了号码听筒里立刻传来“您拨打的号码是空号请核实后再拨”对方直接拒接。情况二实际调试补充在和别人联调mqtt通信时候, 我自己电脑有mqtt服务器的部署, netstat | grep 1883 发现mqtt连接的ip端口是: 127.0.0.1:1883意思是只有本地的mqtt客户端mqtt服务器才处理, 其他非主机的ip数据一律过滤这种情况另外主机在connect三次握手时候服务器收到SYN报文后发给客户端的报文是RST因为客户端请求的ip和端口, 没有对应的MQTT服务器处理所以我电脑粗暴的挂断了情况三路由器“迷路”或“堵死”—— 错误码 EHOSTUNREACH主机不可达或 ENETUNREACH网络不可达 发生原因你发出的请求在前往服务器的路上被某个中间路由器拦截了。路由器回复了一个ICMP错误相当于发回一条短信说“目的地找不到”。 底层行为这是一种软错误软伤。内核不慌不忙先缓存这条“找不到路”的报错信息然后继续重传SYN请求就像在楼下固执地按门铃。 结果如果重传了75秒依然没收到任何回复内核才会把之前缓存的“找不到路”的信息翻出来作为最终错误返回给程序。 生活类比你打电话接通了交换机交换机回复“您拨打的地区不在服务区”但系统没立马挂断而是尝试帮你转接了好几次最后转接失败才告诉你“暂时无法接通”。bind函数避坑两个关于 IP 的细节 细节1 服务器绑定了特定 IP 会怎样 假设你的服务器有 192.168.1.10内网和 203.0.113.5公网两个 IP。 如果你的 bind 指定了内网 IP那么客户端只能用内网地址访问用公网 IP 访问会被拒绝。如果你写 INADDR_ANY通配则两个 IP 都能访问。 细节2 客户端没绑 IP内核怎么选源 IP 原文解释了这取决于路由表。 比如你要访问百度公网内核发现数据包必须走外网网关它就会自动把源 IP 设为公网网卡的那个 IP。不需要你手动填客户端不要bind 不是说不能而是不写bind省事全交给内核自动分配就好了直接connect的时候内核会帮你分配源ip portbind时候以下组合搭配四种情况:
返回列表