2016-11-24 2 views
2

ich die Unterschiede zwischen den beiden berüchtigten Fehler in tcp gelernt haben:wie "Verbindung von Peer zurückgesetzt" reproduzieren

  • [Errno 54] Connection reset by peer
  • [Errno 32] Broken pipe

Beide Fehler einer Seite des tcp sind Verbindung aus unbekannten Gründen geschlossen, und die andere Seite kommuniziert immer noch damit.

  • wenn die andere Seite write etwas wird Broken pipe
  • geworfen, wenn die andere Seite read etwas, Connection reset by peer geworfen wird

Ich konnte Broken pipe mit Python-Codes unten reproduzieren.

# tcp_server.py 
def handler(client_sock, addr): 
    try: 
     print('new client from %s:%s' % addr) 
    finally: 
     client_sock.close() # close current connection directly 

if __name__ == '__main__': 

    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
    sock.bind(('', 5500)) 
    sock.listen(5) 

    while 1: 
     client_sock, addr = sock.accept() 
     handler(client_sock, addr) 

Wie für Client

>>> sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
>>> sock.connect(('', 5500)) 
>>> sock.send('a') 
1 
>>> sock.send('a') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
socket.error: [Errno 32] Broken pipe 

Wenn der Client zuerst send, ein RST Paket vom Server zum Client von diesem Moment an wird send immer Broken pipe werfen gesendet wird.

Alles oben ist in meinem Verständnis. Allerdings, wenn der Client vom Server zu lesen, Sie ihn immer wieder leere Zeichenfolge statt throw Connection reset by peer

>>> sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
>>> sock.connect(('', 5500)) 
>>> sock.recv(1024) 
'' 
>>> sock.recv(1024) 
'' 
>>> sock.recv(1024) 
'' 
>>> sock.recv(1024) 

Ich bin hier verwirrt, oder im Allgemeinen, wie die Connection reset by peer zu reproduzieren?

+0

Sie senden einen Reset mit der Option SO_LINGER hier skizziert: http://stackoverflow.com/a/ 6440364/642070 – tdelaney

+0

@tdelaney noch recv leere Zeichenfolge –

+0

Es hat für mich funktioniert. Ich musste eine kurze Wartezeit im Server hinzufügen, damit die RST nicht mit der Verbindung zurückkommt. – tdelaney

Antwort

2

Sie können die Socket "linger" -Option auf 0 setzen und den Socket schließen, um ein Reset zu senden. Aktualisieren der Server

import socket 
import struct 
import time 

# tcp_server.py 
def handler(client_sock, addr): 
    try: 
     print('new client from %s:%s' % addr) 
     time.sleep(1) 
    finally: 
     client_sock.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, 
      struct.pack('ii', 1, 0)) 
     client_sock.close() # close current connection directly 

if __name__ == '__main__': 

    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
    sock.bind(('', 5500)) 
    sock.listen(5) 

    while 1: 
     client_sock, addr = sock.accept() 
     handler(client_sock, addr) 

Und laufen diesen Client

import socket 
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
sock.connect(('', 5500)) 
print(sock.recv(1024)) 

I

bekam
Traceback (most recent call last): 
    File "tcpclient.py", line 5, in <module> 
    print(sock.recv(1024)) 
ConnectionResetError: [Errno 104] Connection reset by peer 
+0

Danke. Ihre Codes haben die Ausnahme ausgelöst. Dann noch eine Frage: Warum haben sich 'send' und' recv' hier anders verhalten? –

Verwandte Themen