web-dev-qa-db-fra.com

Python socket.error: [Errno 104] Connexion réinitialisée par un homologue

J'ai un code où il y a 13 clients qui doivent se connecter au serveur. Ensuite, le serveur compte sur les données fournies par le client. Après que les rôles se sont transformés - le serveur devient un client et les clients deviennent des serveurs pour recevoir les données. Le problème est que lorsque vous essayez d'établir la première connexion, les 13 clients tentent de se connecter au serveur. Je continue à avoir cette erreur: [Errno 104] Connection reset by peer. J'ai essayé des solutions de contournement, par exemple, en essayant de vous connecter 5 fois dans un deuxième intervalle, mais rien ne fonctionne.

Voici mon code:

server.py

import socket, pickle, numpy as np
import struct
import math


while 1:
    Host = ''
    PORT = 50007
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind((Host, PORT))
    s.listen(13)

adresses = []
ports = []

i = 0
print("receiving...")
while i < 13:
    i += 1    
    #wait to accept a connection - blocking call
    conn, addr = s.accept()
    print ('Connected with ', addr)
    adresses.append(addr[0])
    buf = b''
    while len(buf) < 4:
        buf += conn.recv(4 - len(buf))
    length = struct.unpack('>I', buf)[0]
    data = b''
    l = length

    while l > 0:

        d = conn.recv(l)
        l -= len(d)
        data += d

    if not data: break

    M = np.loads(data)

    if i == 1:
        L = M[0]
    else:
        L += M[0]
    ports.append(M[1])
    conn.close() 
s.close()


L /= 993040

packet = pickle.dumps(L)
length = struct.pack('>I', len(packet))
packet = length + packet

print("sending...")
for kl, addr in enumerate(adresses):
    Host = addr
    PORT = 50007 + ports[kl]
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((Host, PORT))
    s.sendall(packet)
    s.close()

client.py

def connection(centers, kl):

    Host = "192.168.143.XX"
    PORT = 50007
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.settimeout(3600)
    try:
        s.connect((Host, PORT)) # HERE IS AN ERROR
        s.settimeout(None)
        packet = pickle.dumps([centers, kl]) ## ???
        length = struct.pack('>I', len(packet))
        packet = length + packet
        s.sendall(packet) # OR HERE IS AN ERROR
        s.close()
    except Exception as e:
        print(e)
        print('error ', kl)
        s.close()
        return np.zeros(centers.shape)    


    Host = ''
    PORT = 50007 + kl
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind((Host, PORT))

    s.listen(2)

    i = 0
    while i < 1:
        #wait to accept a connection - blocking call
        conn, addr = s.accept()
        i += 1
        print ('Connected with ', addr)
        buf = b''
        while len(buf) < 4:
            buf += conn.recv(4 - len(buf))

        length = struct.unpack('>I', buf)[0]
        data = b''
        l = length
        while l > 0:
            d = conn.recv(l)
            l -= len(d)
            data += d
        if not data: break

        new_centers = np.loads(data)
        conn.close()

    s.close()
    return new_centers

aa = 0
for k in range(99):
    print(k)
    centers = some_function(centers)
    time.sleep(60)
    centers1 = connection(centers, i)
    aa = 0
    while not (centers1.any()) and aa < 5:
        time.sleep(1)
        centers1 = connection(centers, i)
        aa += 1
    centers = centers1

Les 13 clients DOIVENT se connecter au serveur, sinon ils ne passeront pas à la prochaine itération. J'utilise Python 3.4. S'il vous plaît, aidez-moi.

Mettre à jour :

J'ai ajouté des discussions mais l'erreur reste:

[Errno 104] Connexion réinitialisée par un homologue

server.py

import socket, pickle, numpy as np
import struct
import math
from multiprocessing.pool import ThreadPool

def clientthread(conn, L):
    buf = b''
    while len(buf) < 4:
        buf += conn.recv(4 - len(buf))
    length = struct.unpack('>I', buf)[0]
    data = b''
    l = length
    while l > 0:
        d = conn.recv(l)
        l -= len(d)
        data += d
    M = np.loads(data)


    return(M)


j = 0
while 1:
    Host = ''
    PORT = 50007
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind((Host, PORT))
    s.listen(2)
    #print('0')

    adresses = []
    ports = []

    i = 0
    print("receiving...")
    while i < 13:
        i += 1    
        #wait to accept a connection - blocking call
        conn, addr = s.accept()
        print ('Connected with ', addr)
        adresses.append(addr[0])
        pool = ThreadPool(processes=13)
        async_result = pool.apply_async(clientthread, (conn, i,))
        M = async_result.get()  
        conn.close() 

        if i == 1:
            L = M[0]
        else:
            L += M[0]
        ports.append(M[1])
    s.close()


    L /= 993040

    packet = pickle.dumps(L)
    length = struct.pack('>I', len(packet))
    packet = length + packet

    for kl, addr in enumerate(adresses):
        Host = addr
        PORT = 50007 + ports[kl]
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((Host, PORT))
        s.sendall(packet)
        s.close()
4
potockan

Il semble que les clients étaient connectés au serveur, mais ils ont rencontré une exception "[Errno 104] Connection reset by peer" lorsqu'ils ont tenté d'envoyer des données. Pour la première fois, Python déclenche une exception "[Errno 104] Connection reset by peer", puis pour la deuxième fois et davantage, vous obtenez une exception "[Errno 32] Broken pipe" côté client.

Cela peut signifier que le serveur est actif et à l'écoute sur le port (sinon, vous obtiendrez "[Errno 111] Connection refused" exception on the client side". Cela signifie également que le serveur est en panne avant la fermeture de la connexion, car si la connexion était fermée côté serveur avant l'envoi des données sur le serveur. côté client, le client rencontrerait une exception "[Errno 32] Broken pipe".

"Connexion réinitialisée par homologue" est l'équivalent TCP/IP de raccrocher le téléphone. C'est plus poli que de ne pas répondre, en laissant quelqu'un en suspens. Mais ce n'est pas le FIN-ACK attendu du converseur TCP/IP vraiment poli. ( D'une autre réponse stackoverflow )

2
Mahyar Hosseini

Vous allez devoir utiliser le threading sur le serveur.
Pour une explication simple, voir: http://www.binarytides.com/python-socket-server-code-example/
Les entrailles de l'exemple simple donné sont: 

import socket
import sys
from thread import *

Host = ''   # Symbolic name meaning all available interfaces
PORT = 8888 # Arbitrary non-privileged port

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'

#Bind socket to local Host and port
try:
    s.bind((Host, PORT))
except socket.error as msg:
    print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
    sys.exit()

print 'Socket bind complete'

#Start listening on socket
s.listen(10)
print 'Socket now listening'

#Function for handling connections. This will be used to create threads
def clientthread(conn):
    #Sending message to connected client
    conn.send('Welcome to the server. Type something and hit enter\n') #send only takes string

    #infinite loop so that function do not terminate and thread do not end.
    while True:

        #Receiving from client
        data = conn.recv(1024)
        reply = 'OK...' + data
        if not data: 
            break

        conn.sendall(reply)

    #came out of loop
    conn.close()

#now keep talking with the client
while 1:
    #wait to accept a connection - blocking call
    conn, addr = s.accept()
    print 'Connected with ' + addr[0] + ':' + str(addr[1])

    #start new thread takes 1st argument as a function name to be run, second is the Tuple of arguments to the function.
    start_new_thread(clientthread ,(conn,))

s.close()
0
Rolf of Saxony