电脑突然断网会发生什么

问题:电脑突然断网会发送什么?

首先问题的前提是电脑和外部有进行连接,讨论已经建立的连接才有意义。
新建连接看断网时间长短决定握手成功与否。

写个简单的发包程序,为了便于单步调试,直接用python:

import socket
import sys

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)                 
s.connect((sys.argv[1] , int(sys.argv[2])))
s.sendall("GET /404 HTTP/1.0\r\n\r\n")
while True:
    line = s.recv(4096)
    if line:
        print line
    else:
        break
s.close()

直接pdb模式运行:python -m pdb scripts/test_socket.py xx 8000
目标机器运行python -m SimpleHTTPServer监听8000端口。
当connect成功后,在目标机器上利用iptables模拟断网:

iptables -A INPUT -p tcp  --dport 8000 -j DROP

sendall函数将数据写入tcp协议栈缓冲区后,卡在recv函数,本地抓包: img 重传一定次数后,会发送RST给目标机器断掉连接,recv函数抛出timeout错误:

-> s.sendall("GET /404 HTTP/1.0\r\n\r\n")
(Pdb) c
Traceback (most recent call last):
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pdb.py", line 1314, in main
    pdb._runscript(mainpyfile)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pdb.py", line 1233, in _runscript
    self.run(statement)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/bdb.py", line 400, in run
    exec cmd in globals, locals
  File "<string>", line 1, in <module>
  File "scripts/test_socket.py", line 8, in <module>
    line = s.recv(4096)
error: [Errno 60] Operation timed out

如果是TCP协议栈写满后,会阻塞在sendall出,然后抛出Broken pipe:

(Pdb) c
-> s.sendall("*"*406000)
(Pdb) c
Traceback (most recent call last):
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pdb.py", line 1314, in main
    pdb._runscript(mainpyfile)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pdb.py", line 1233, in _runscript
    self.run(statement)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/bdb.py", line 400, in run
    exec cmd in globals, locals
  File "<string>", line 1, in <module>
  File "scripts/test_socket.py", line 6, in <module>
    s.sendall("*"*406000)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket.py", line 228, in meth
    return getattr(self._sock,name)(*args)
error: [Errno 32] Broken pipe

如果短暂断网后立马恢复,sendall函数执行前添加iptables,sendall后立马清掉规则(考验手速)。
抓包如下: img 可以看到重传一定次数后,可恢复访问。如果时间短一般对业务没什么重大影响(网络抖动经常存在)。

-> s.sendall("GET /404 HTTP/1.0\r\n\r\n")
(Pdb) c
HTTP/1.0 404 File not found

Server: SimpleHTTP/0.6 Python/2.7.5
Date: Sun, 05 Apr 2020 15:35:53 GMT
Content-Type: text/html
Connection: close

<head>
<title>Error response</title>
</head>
<body>
<h1>Error response</h1>
<p>Error code 404.
<p>Message: File not found.
<p>Error code explanation: 404 = Nothing matches the given URI.
</body>

The program finished and will be restarted

结论:
1、如果连接之间没有数据交换,断网没影响,tcp也识别不出来这种情况,需要心跳来检测这种情况
2、如果断网时有数据发送,tcp重试一定次数后会断掉连接,如果短暂断网,重传恢复,对业务基本没啥重要影响