TCP 自连接

  • tcp连接两段使用了同一端口进行连接,而tcp并没有报错并且连接成功。即localhost:x --> localhost:x
  • 只存在于 tcp 本地通信,而且客户端先于服务端启动

代码:

https://github.com/Anita-Mul/recipes/blob/master/python/self-connect.py

#!/usr/bin/pythonimport errno
import socket
import sys
import timeif len(sys.argv) < 2:print "Usage: %s port" % sys.argv[0]print "port should in net.ipv4.ip_local_port_range"
else:port = int(sys.argv[1])   # 命令行输入端口号for i in range(65536):try:sock = socket.create_connection(('localhost', port)) # 尝试对端口号发起连接print "connected", sock.getsockname(), sock.getpeername() # 连接成功,打印本机地址和对端地址time.sleep(60*60)  # 休眠一小时except socket.error, e:if e.errno != errno.ECONNREFUSED:break

测试

  • 查看本机有哪些端口正在监听

     netstat -ltnp
    
  • 选择一个正在监听的端口,启动程序
    python self-connect.py 22
    
  • 查看本机端口号的范围【ip_local_port_range
    sysctl -A |grep range
    
  • 选择一个不在监听的端口,启动程序
    发现也会启动成功

    python self-connect.py 31000
    # 查看 31000 端口占用情况,发现只有自连接的情况出现
    netstat -tpn|grep 31000
    

原因

  • tcp在发起连接时,会从 ip_local_port_range 中选取一个临时端口号,选定端口号后再向服务器的端口发送请求。如果指定端口在侦听,那么这个随机端口就不会选取到这个端口(连接到22端口,不会发生自连接),如果指定端口没有在侦听,那么就有可能发生自连接。
  • 客户端不断地尝试连接 31000 端口,每次都会随机分配一个临时端口(临时端口分配规则是,给上一次分配的端口号+1)。在多次尝试后,会出现分配的临时端口和目的端口一样,此时就会出现自连接情况了
    • 客户端在选取了一个临时端口 x 后,该端口就被加入内核中,客户端在发送syn报文到31000端口(x to 31000),但因为 31000 没有在监听,因此 连接失败 。

    • 在此尝试连接,重新选取临时端口号 x + 1 ,再次尝试连接 … 失败。

    • 第n次尝试时,选取的临时端口号刚好是 31000 端口,然后向 31000 端口发起syn报文,此时在内核中检测到了刚加入的端口,然后连接成功。

解决方法

  • 在连接成功后检测一下是否为自连接,如果是自连接断开即可

    // 检测是否为自连接:判断本机地址是否等于对端地址
    bool isSelfConnection(const Socket& sock)
    {return sock.getLocalAddr() == sock.getPeerAddr();
    }// 连接的处理:是自连接则断开连接
    TcpStreamPtr TcpStream::connectInternal(const InetAddress& serverAddr, const InetAddress* localAddr)
    {TcpStreamPtr stream;Socket sock(Socket::createTCP());if (localAddr){sock.bindOrDie(*localAddr);}if (sock.connect(serverAddr) == 0 && !isSelfConnection(sock)) // 连接成功 且 不是自连接{// FIXME: do poll(POLLOUT) to check errorsstream.reset(new TcpStream(std::move(sock))); // 设置stream,将连接移动到strean中}return stream;  // 如果不设置stream等于放弃sock的连接(sock出作用域后会自动释放,连接自动断开)
    }
    

Linux C/C++网络编程实战-陈硕-笔记7-TCP自连接相关推荐

  1. Linux C/C++网络编程实战-陈硕-笔记20-使用非阻塞IO

    基于IO复用(非阻塞IO)实现的 netcat 使用非阻塞IO可以有效避免上述情况的发生.但非阻塞IO在编程上要比阻塞IO更难,并且在程序的维护上比较痛苦.一般使用非阻塞IO编程时建议使用一些封装好的 ...

  2. Linux C/C++网络编程实战-陈硕-笔记15-如何正确使用 TCP

    netcat netcat 除了读取 socket 描述符,还要读取 stdin 和 stdout 并发模型 thread-per-connection IO 复用和非阻塞 IO 配合 如何安全的关闭 ...

  3. Linux C/C++网络编程实战-陈硕-笔记10-网络时间同步

    网络时间同步(NTP)原理 Device A发送一个NTP报文给Device B,该报文带有它离开Device A时的时间戳,该时间戳为10:00:00am(T1). 当此NTP报文到达Device ...

  4. Linux C/C++网络编程实战-陈硕-笔记3-回顾基础的 Sockets API

    性能指标 带宽(Bandwidth):每秒收发的数据量,MB/s.(只关注数据量,不关注消息数) 吞吐量(Throughput):消息/s.查询/s(QPS).事物数/s(TPS) 延迟(Latenc ...

  5. Linux C/C++网络编程实战-陈硕-笔记2-一个TCP的简单实验

    实验环境 命令 dd命令: 用于读取.转换并输出数据. 可从标准输入或文件中读取数据,根据指定的格式来转换数据,再输出到文件.设备或标准输出. 参数: if=文件名:输入文件名,默认为标准输入.即指定 ...

  6. Linux C/C++网络编程实战-陈硕-笔记11-Roundtrip代码分析

    代码 UDP, two threads recipes/tpc/roundtrip_udp.cc UDP with muduo, single thread muduo/examples/roundt ...

  7. Linux C/C++网络编程实战-陈硕-笔记17-多个版本的Netcat概览

    操作模式 对于 netcat 程序,存在两种模式,即 服务端 和 客户端, 它们的区别在于连接建立的方式. 一旦连接建立,客户端/服务器 的行为都是一样的,使用两个并行的循环处理: 从标准输入,写到 ...

  8. 网络编程实践陈硕笔记零

    1.理查德森的unix网络编程有两样不足:一消息格式处理,特别是非阻塞IO上处理TCP分包问题:二是并发模型稍显陈旧,传统高并发采用事件驱动加非阻塞IO方式. 2.程序员面对的网络术语 Etherne ...

  9. 【网络编程实践--陈硕】学习笔记 | 汇总目录

    本文参考<网络编程实践>–陈硕(Muduo作者)视频课程所写.基于课程内容所做归纳和整理. <网络编程实战>配套页面:http://chenshuo.com/pnp Blog ...

最新文章

  1. android 刷新某条数据_Android 支持刷新、加载更多、带反弹效果的RecyclerView
  2. Kotlin学习 PART 1:kotlin定义和目的
  3. 仓储模式到底是不是反模式?
  4. 一统江湖的大前端(5)editorconfig + eslint——你的代码里藏着你的优雅
  5. 使用Redis Desktop Manager连接Redis服务器
  6. aⅴgo安装包下载_Mysql 安装
  7. Android View动画
  8. Nashorn Multithreading and MT-safety
  9. linux下tpcc测试mysql_tpcc_mysql性能测试
  10. java list indexof_Java LinkedList indexOf()方法
  11. hdu 5335 Walk Out(bfs+斜行递推) 2015 Multi-University Training Contest 4
  12. 无码编程:无代码软件开发大行其道
  13. 163邮箱注册及授权密码开通
  14. My Sixtieth Page - N皇后 - By Nicolas
  15. Flixel横板游戏制作教程(十)—Pickups(拾取道具)
  16. android youtube webview,在Android WebView中播放Youtube HTML5嵌入式视频
  17. 如何用golang远程控制浏览器
  18. 明源售楼系统技术解析 签约管理(二)
  19. AnyTrans for Mac(ios数据传输工具)
  20. SVN黑马程序员笔记

热门文章

  1. Given any string of N (=5) characters, you are asked to form the characters into the shape of U.
  2. scheduleAtFixedRate和scheduleWithFixedDelay的区别
  3. ChatGPT向癌症开了一枪
  4. Jt808协议头部包解析
  5. jsonpath使用
  6. python的:0 if x == y else 1 if x y else -1
  7. 永不抵达的列车nbsp;nbsp;《nbsp;中国青年报nbsp;》
  8. 洛谷 P2053 [SCOI2007]修车 网络流 最小费用最大流 Dinic+Spfa
  9. Linux启动hbase的shell命令出现警告_Linux 系统故障修复和修复技巧
  10. 应用层:电子邮件、MIME、SMTP协议、POP3协议