如何重用TCP套接字python

时间:2017-12-17 10:23:25

标签: python sockets tcp error-handling

我想做什么

我想再次使用sTCP.connect()和不同的IP和PORT

我的问题

在while的下一次互动中(当我有一个不同的IP和PORT而不是最后一个)时,我得到一个错误:"此连接已在使用" 我能做些什么才能让它发挥作用? 套接字在while循环之前声明。为了清除我只会显示while循环:

while y != numero_de_lineas:
        print "Interaccion numero", y

        if reintentar == 1:
            print y
            reintentar = 0


        tupla = (str(iplista[y]),int(portlista[y]))
        sUDP.sendto(mensaje1,tupla)
        try:
            if reintentar != 1:  #si estoy reintentando no quiero otro timeout
                sUDP.settimeout(time_out)
                respuesta1 , address1 = sUDP.recvfrom(BUFFER_SIZE)

            #si todo va bien tengo respuesta1
            #print(respuesta1) #recibo ni ok ni no
            if (respuesta1 == "ok") or (reintentar != 1):




                sTCP.connect((iplista[y],int(portlista[y])))  #SE CONECTA N VECES, HAY QUE ACCEPTAR OTRA CONEXION CON .accept()
                contenido_fichero = fichero.read()  #lo que hay dentro de ./fichero.txt
                sTCP.send(contenido_fichero)
                try:

                    sTCP.settimeout(time_out_TCP) #esperamos 10 segundos
                    respuesta2 = sTCP.recv(BUFFER_SIZE)
                    #LIBERAMOS LA CONEXION TCP

                    #print(respuesta2) #recibo transferdone
                    #si recibe respuesta1 y respuesta2 paramos
                    #empezamos con el calculo de la huella con el server aceptado iplista[y],portlista[y]
                    huella_md5 = md5.new() #creamos la huella
                    huella_md5.update(contenido_fichero) #actualicamos su contenido (le podemos meter mas strings despues)
                    huella_md5_calculada = huella_md5.hexdigest() #huella en string



                    sUDP.sendto(huella_md5_calculada,tupla)
                    try:
                        sUDP.settimeout(time_out_TCP) #porque son 10 segundos
                        respuesta3 , address3 = sUDP.recvfrom(BUFFER_SIZE)

                        if respuesta3 == "md5sum ok":
                            print "Copia de fichero en servidor",iplista[y],"correcta"

                        if respuesta3 == "md5sum error":
                            print "Error en la copia del fichero en el servidor",iplista[y],"Se vuelve a intentar" #REINTENTAR
                            reintentar = 1



                    except socket.timeout:
                        print "Error en la copia del fichero en el servidor",iplista[y],". Finalizado el intento"


                except socket.timeout:
                    print "Error en la transferencia con el servidor",str(iplista[y])
            if respuesta1 == "no":
                print "Error. El servidor",iplista[y],"no acepta el fichero"

        except socket.timeout:
            print "Error: no hay respuesta por parte del servidor",  iplista[y] , "en el puerto", portlista[y]
            #if y == (numero_de_lineas-1):  #-1 porque para y el cero cuenta
                #sys.exit()  #si todos fallaron al conectar udp nos salimos

编辑:

这是套接字声明(它位于while循环之前)

 try: #tenemos que crear el socket tcp en cada interaccion porque sino ya esta en uso
    sUDP = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)     #UDP
    sTCP = socket.socket(socket.AF_INET,socket.SOCK_STREAM)    #TCP
except socket.error :
    print "Error al crear socket TCP"
    sys.exit()

2 个答案:

答案 0 :(得分:1)

您无法在同一个socket实例上连接两次。您必须每次都创建一个新的socket对象,即您需要

sTCP = socket.socket(...)

每次致电.connect(...)之前。

不要忘记.close()和/或.shutdown()旧套接字实例。

答案 1 :(得分:1)

我认为您使用的是不同的目标(IP,端口)对,因为y永远不会更改。地址由:

给出
(iplista[y],int(portlista[y]))

因此,如果y永远不会更改,则将使用相同的地址。由于连接仍然在上一个循环中打开,因此新的连接尝试失败。

也许你应该在循环中递增y

完成连接后,您还应关闭连接,以确保正确释放资源。使用sTCP.shutdown()后跟sTCP.close()。然后为下一个连接创建一个新套接字(N.B.表示你需要在循环中创建套接字)。