如何重用TCP套接字python

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何重用TCP套接字python相关的知识,希望对你有一定的参考价值。

What I want to do

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

My problem

在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

Edit:

这是套接字声明(它位于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()
答案

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

sTCP = socket.socket(...)

每次你打电话给.connect(...)之前。

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

另一答案

我不认为你使用不同的目标(IP,端口)对,因为y永远不会改变。地址由下式给出:

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

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

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

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

以上是关于如何重用TCP套接字python的主要内容,如果未能解决你的问题,请参考以下文章

Python 之 Socket编程(TCP/UDP)

TODO:Golang语言TCP/UDP协议重用地址端口

如何在 python asyncio 中处理 tcp 客户端套接字自动重新连接?

健壮的连续 TCP 连接(python 套接字)

如何从片段到活动而不会干扰片段的可重用性

条件片段和导航重用