Pythonのソケットプログラミング3:長い接続、短い接続、およびハートビート
ロング接続:オープンソケット接続、データの送受信は、接続はすぐに閉じられていない、あなたが複数回送信し、パケットを受信することができます。
短い接続:ソケット接続、送信を開き、データを受信し、すぐに接続を閉じます。
ハートビート:もはや接続状態を維持するために、パケットのデータ通信、送信タイミング(ハートビート)とが接続されています。
Pythonでは、実際には、それほど複雑なものをしない、心拍検出が自動的にTCPプロトコル層で維持され、Pythonインタフェースの設定は、直接コードに、それを呼び出す必要があります:
サーバ側:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
#coding=utf-8
__author__
=
'药师Aric'
'''
server端
长连接,短连接,心跳
'''
import
socket
BUF_SIZE
=
1024
host
=
'localhost'
port
=
8083
server
=
socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((host, port))
server.listen(
1
)
#接收的连接数
client, address
=
server.accept()
#因为设置了接收连接数为1,所以不需要放在循环中接收
while
True
:
#循环收发数据包,长连接
data
=
client.recv(BUF_SIZE)
print
(data.decode())
#python3 要使用decode
# client.close() #连接不断开,长连接
|
クライアント側:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
#coding=utf-8
__author__
=
'药师Aric'
'''
client端
长连接,短连接,心跳
'''
import
socket
import
time
host
=
'localhost'
port
=
8083
client
=
socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE,
1
)
#在客户端开启心跳维护
client.connect((host, port))
while
True
:
client.send(
'hello world\r\n'
.encode())
print
(
'send data'
)
time.sleep(
1
)
#如果想验证长时间没发数据,SOCKET连接会不会断开,则可以设置时间长一点
|
TCPハートビート・メカニズム
TCP自身のハートビートパケット、TCPのSO_KEEPALIVEオプション、2時間の周波数をスキップし、システムのデフォルトのデフォルトに基づいて、ハートビートメカニズムの実装では、2時間以上後に、ローカルのTCP実装は、リモートソケットにパケットを送信します。もしリモートソケット応答が返送されていない、TCPは、応答を受信するまで、11分を達成しようとしていきます。それ以外の場合は、自動的にソケット接続を切断します。
TCPハートビートを意味
TCP初心者の間違い-ハートビート意味
の背景には、
最近、多少の誤差があり、多くの初心者は、TCPのためにTCPを使用することがわかった、とも疑問を持っていたこれらのピットは、私は素敵な場所を持っていた、学生の数をインタビューしました。いくつかのオンラインの記事では、唯一の結論と実際にそこに直接付与されているこれらの問題の詳細な分析を持っていた私は、この連載では、これらの問題のインとアウトを教えてくれますので、誰も明確に、それらのインとアウトを説明しませんTCPの初心者の大半はこれらのピットを避けるためにすることを期待して、アウト。
質問
私は多くの場合、1つのネットワーク・ケーブル・アンプラグの終了または電源を削除する場合は、もう一方の端は、通知を受信するために、接続を確立するために、A、Bのとき、TCPの終了であるインタビューの中で尋ねる質問を?
答えはノーですが、ごく少数の人だけが正しく、この質問に答えることができます。
その理由
TCPは合意がある接続であるが、これは、回路の実際の接続が、仮想回線があることを意味するものではありません。TCPは接続と切断されたデータを、送信することにより行われて確立すること、私たちはしばしばスリーウェイハンドシェイクは、4回を振っていると言います。先に前方にのみデータを両端のデバイスをルーティングするようにA接続、TCPに代わってデータの保存のTCP状態、の両端は、これらのデータは実際の意味を表しているかわからない、保存するようにしたしませんでした先にちょうど前方に、デバイスにデータを概念を接続しない経路の途中にある任意のステータス情報のみを送信者と受信者の両方の端部は、実データがデータ伝送接続を表している知っています。
しかし、これは、あなたがデータを切断することはできません送信しないのであれば、ポイントを示しています。通常の状況下では、ときにプロセスの近く又は終わりにTCPソケットAコールの終了は、オペレーティング・システムは、TCPプロトコルに従ってFINパケットを送信します。、端末Bが受信された切断されます。上記の例外があったときには:ネットワークケーブルを抜いたり、電源遮断され、FINパケットをオフに送信する機会を総括ません。ルーティングデバイスと、直接既知のA装置も接続が切断されているが、切断のルーティングデバイスA B側の端部に通知することは不可能であるので、ルーティングデバイスは、接続の状態は保存されません。Bは、パケットがまだ接続されたままになります壊れたデータを受信しません。したがって、電源端子BカットオフA側または引き出し線が断線を通知することができません。
解决方案
保持连接并不是毫无代价的,如果这种异常断开的连接有很多,那么势必会耗费大量的资源,必须要想办法检测出这种异常连接。
检测的方法很简单,只要让B端主动通过这个连接向A端继续发送数据即可。上文说过,A端异常断开后,和A端直接连接的路由器是知道的。当B端发送的数据经过转发后到达这个路由器后,必然最终会返回B端一个目的不可达。此时B端立刻就会知道这条连接其实已经异常断开了。
但是B端不可能知道什么时候会出现这种异常,所以B端必须定时发送数据来检测连接是否异常断开。数据的内容无关紧要,任何数据都能达到这个效果。这个数据就是我们经常在TCP编程中所说的心跳。
KEEP_ALIVE
TCP协议本身就提供了一种这样的机制来探测对端的存活。TCP协议有一个KEEP_LIVE开关,只要打开这个开关就会定时发送一些数据长度为零的探测心跳包,发送的频率和次数都可以设置,具体的方法在网上搜索tcp keepalive即可,网上有很多文章,这里不再赘述。
应用层心跳
除了使用TCP协议本身的保活开关机制,还可以在应用层主动发送心跳数据包,那么在应用层主动发送心跳数据包的方式和TCP协议本身的保活机制有什么区别呢?
应用层的心跳数据包会耗费更多的带宽,因为TCP协议的保活机制发送的是数据长度为零心跳包,而应用层的心跳数据包长度则必然会大于0。
应用层的心跳数据包可以带一些应用所需要的数据,随应用自己控制,而TCP协议的保活机制则是对于应用层透明的,无法利用心跳携带数据。
双向心跳
那么是否只是一端向另一端发送心跳就行了呢?显然不行。因为两端都有可能发生异常断开的情况。所以TCP连接的两端必须都向对端发送心跳。
总结
TCP中不使用心跳通常来说并没有什么问题,但是一旦遇到了连接异常断开,那么就会出现问题。所以任何一个完善的TCP应用都应该使用心跳。
心跳的意义对于很多TCP的初学者而言是个大坑,我写这篇文章希望初学者能够在编写TCP程序时避免这个坑,同时也希望面试者能够深入理解TCP的心跳机制,能够取得更好的面试结果。
test