Solución de problemas colgada de zócalo UDP en un código de aplicación de Python Server -- python campo con sockets campo con network-programming campo con udp camp Relacionados El problema

Troubleshooting hanged UDP socket in a Python server application code


0
vote

problema

Español

Estoy escribiendo una aplicación de servidor UDP que sirve como un final posterior a los dispositivos montados en automóvil Teltonika FMB630.

Ya me encargué de los específicos del protocolo y la decodificación, el problema que estoy enfrentando se relaciona con el zócalo UDP usado.

My UDP Server tiene que enviar un acuse de recibo al dispositivo cliente al recibir un mensaje (que es el protocolo), sin embargo, si envío esos ACK, la toma del servidor deja de recibir datos después de un rato.

El objeto Socket UDP del servidor se pasa a un concurrent.futures.ThreadPoolExecutor6 que incendió una función ( send_ack ) que envía el ACK, sin embargo, este no es el problema porque intenté llamar < Código> send_ack en el hilo principal, después de recibir datos y se produce el mismo problema.

Sospecho que el problema es que el dispositivo remoto se rompe de alguna manera la conexión o el ISP o MNO no encienden el paquete de respuesta (este es un dispositivo GPRS) y luego el método concurrent.futures.ThreadPoolExecutor9 que se utiliza para Envíe el reconocimiento, de alguna manera se congela de otras operaciones de socket, específicamente composer update0 llamado en el bucle de hilo principal.

Escribí dos scripts para ilustrar la situación:

udp_test_echo.py:

  composer update111  

udp_test_client.py:

  composer update2  

Ejecutar UDP_TEST_ECHO.PY EN UN TERMINAL Y UDP_TEST_CLIENTE.PY En OTRO, VEREMOS OPERIOR NORMAL PERO SI USTED CTRL + C EL CLIENTE DE PRUEBA Y REJO LLEGADO, verá que el servidor no responde hasta que se reinicie.

¿Hay una manera de tiempo de espera una operación de envío específica desde una llamada específica a composer update313 sin afectar otras llamadas? (I quiere My composer update4 Llame para bloquear en el hilo principal)

Si i composer update5 en todo el objeto Socket, voy a lidiar con muchas excepciones al esperar los datos en el hilo principal y no me gusta tener que confiar en las excepciones para Operación adecuada del programa.

Original en ingles

I am writing a UDP server application that serves as a back end to Teltonika FMB630 car mounted devices.

I already took care of the protocol specifics and decoding, the problem I am facing relates to the UDP socket used.

My UDP server has to send an acknowledgement to the client device upon receiving a message (that is the protocol), however, if I send those ACKs, the server socket stops receiving data after a while.

The server's UDP socket object is passed to an concurrent.futures.ThreadPoolExecutor that fires a function (send_ack) that sends the ACK, however this is not the issue because I tried calling send_ack in the main thread, after receiving data and the same issue occurs.

I suspect the problem is the remote device somehow breaks the connection or the ISP or MNO doesn't route the reply packet (this is a GPRS device) and then the socket.send() method that is used to send the acknowledge, somehow freezes other socket operations, specifically recvfrom_into called in the main thread loop.

I wrote two scripts to illustrate the situation:

udp_test_echo.py :

#!/usr/env/bin python  import socket import concurrent.futures  def send_ack(sock, addr, ack):     print("Sending ACK to {}".format(addr))     sock.connect(addr)     print("connected to {}".format(addr))     sock.send(ack)     print("ACK sent to {}".format(addr))  s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.bind(("127.0.0.1", 1337)) data = bytearray([0] * 10)  executor = concurrent.futures.ThreadPoolExecutor(max_workers=4)  while True:     print("listening")     nbytes, address = s.recvfrom_into(data)     print("Socket Data received {} bytes Address {}".format(nbytes, address))     print("Data received: ", data, " Echoing back to client")     executor.submit(send_ack, s, address, data[:nbytes]) 

udp_test_client.py:

#!/usr/env/bin python  import socket import time import random  def get_random_bytes():     return bytearray([random.randint(0,255) for b in range(10)])  ip = "127.0.0.1" port = 1337 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.connect((ip, port))  while True:     stuff_to_send = get_random_bytes()     print("Sending stuff", stuff_to_send)     s.sendall(stuff_to_send)     print("reply: ", s.recvfrom(10))     time.sleep(0.1) 

Running udp_test_echo.py in one terminal and udp_test_client.py in another, we see normal operation but if you Ctrl+C the test client and re run it, you will see that the server doesn't respond until it is restarted.

Is there a way to timeout a specific sending operation from a specific call to socket.send() method without affecting other calls ? (I want my socket.recvfrom_into call to block on the main thread)

If I settimeout on the entire socket object, I am going to have to deal with many exceptions while waiting for data in the main thread and I don't like to have to rely on exceptions for proper program operation.

           

Lista de respuestas

1
 
vote

El culpable fue el socket.connect() Llamar en send_ack , cuando se llama al objeto del socket del servidor, hace que el zócalo ya no esté atado y escuche el puerto especificado en El inicio del programa.

En su lugar, se cambió la función width2 para ser:

  def send_ack(sock, addr, ack):     print("Sending ACK to {}".format(addr))     sock.sendto(ack, addr)     print("ACK sent to {}".format(addr))   

socket.sendto (datos, dirección) utiliza la conexión existente en lugar de comenzar una nueva.

 

The culprit was the socket.connect() call in send_ack, when being called on the server's socket object it causes the socket to no longer be bound and listen on the port specified in the start of the program.

Instead the send_ack function was changed to be:

def send_ack(sock, addr, ack):     print("Sending ACK to {}".format(addr))     sock.sendto(ack, addr)     print("ACK sent to {}".format(addr)) 

socket.sendto(data, address) uses the existing connection instead of starting a new one.

 
 

Relacionados problema

0  TCP o UDP para un simple servicio  ( Tcp or udp for simple service ) 
Para un servicio que solo devuelve un número pequeño cuando se pregunta, como 30, o 10, pero tendría que manejar hasta 5 o más solicitudes en cualquier caso, ...

3  EJEMPLO DESCROMASYC  ( Receivefromasync example ) 
¿Alguien tiene un ejemplo para recibir las obras de ReceiveFromasync con respecto a UDP? No pude encontrar ningún código de muestra. Puedo encontrar unas cuan...

0  C PCAP detectando datagramas entrantes  ( C pcap detecting inbound datagrams ) 
en C Mezcle una toma de datagramas (AF_INET, SOCK_DGRAG) a inaddr_any. Luego, utilice periódicamente este socket para enviar y recibir datagramas, y monitorea...

1  Micrófono UDP Live Audio Streaming  ( Microphone udp live audio streaming ) 
Estoy intentando escribir un programa Java para enviar datos de micrófono en vivo sobre UDP, luego recibir los datos en VLC. Básicamente, estoy usando el mism...

0  Java / Android: UDP - No se pueden recibir paquetes más grandes (pero aún <64K)  ( Java android udp cant receive larger packets but still 64k ) 
Estoy trabajando en una aplicación de Android cliente-Server (dos aplicaciones: un cliente y un servidor). Se espera que el servidor envíe un video al cliente...

8  Trading de alta frecuencia - TCP> UDP?  ( High frequency trading tcp udp ) 
Me dijeron que para un sistema de comercio de alta frecuencia (HFT) que requiere baja latencia, TCP se usa sobre UDP. Me dijeron que con TCP puede hacer que l...

36  La mejor biblioteca C ++ RTP / RTSP [cerrada]  ( Best c rtp rtsp library ) 
cerrado. Esta pregunta no cumple con pautas de desbordamiento de pila . Actualmente no está aceptando respuestas. ...

1  Forzar a un enrutador para mantener un puerto UDP inactivo abierto  ( Force a router to keep a an idle udp port open ) 
Un cliente abre una conexión UDP a mi servidor, después de algún tiempo (10 minutos-24 horas), el servidor necesita enviar datos al cliente, ¡pero encuentra q...

0  Transmisión Sendo falló  ( Broadcast sendto failed ) 
Estoy tratando de transmitir datos, pero la salida es Falló el envío de UDP. Elegí un puerto aleatorio 33333. ¿Qué pasa con mi código? int main() { stru...

0  iOS - CFSocket no recibe devolución de llamada  ( Ios cfsocket not getting callback ) 
Se han solicitado preguntas similares, pero los problemas parecen ser específicos del código, así que, con suerte, esto esté bien. Estoy tratando de escribi...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos