sistema consta de un número de nodos que escuchan en mismo puerto (diferente ip addr de). El sistema [A] envía un datagrama al Sistema [B]. El sistema [B] asincrónicamente responde y envía datagramas de vuelta al [A], todos utilizando el mismo puerto. Aunque [B] identifica los puertos [A] 's, [A] no está escuchando en ese puerto
No estoy seguro de entender el 'todo usando el mismo puerto' frase en esa frase. Si A envía un datagrama a B, B conocerá el IP y el puerto de A inmediatamente (una revisión rápida de la documentación de su biblioteca revela que OnRawData tiene un parámetro struct sockaddr *sa
, si lo transfiere al sockaddr_in*
podrá extraer el par IP: puerto) Puede usar ese IP: puerto para enviar datagramas ay A los recibirá. A no está "escuchando" en ese puerto en el sentido de que no ha llamado a listen() en el socket, sino que A posee un socket que está vinculado a ese puerto (ya sea explícitamente llamando a bind() o al puerto aleatorio asignado por el sistema operativo) recibirá los datos.
Ahora, si desea que TODA su comunicación entre los nodos pase por su puerto fijo, puede hacerlo. Solo tiene que enviar todos sus datagramas a través de su socket de "escucha". Si cada nodo "escucha" en el mismo puerto, significa que cada nodo posee un socket que está vinculado a ese puerto. Si desea que los datagramas enviados de A a B aparezcan desde este puerto fijo, debe enviarlos a través de ese socket. Supongo que es por eso que bind() no funciona para tu socket de envío - A tiene un socket vinculado al puerto X, luego creas otro socket e intentas vincularlo al mismo puerto X, bind() falla ya que el puerto ya está tomado (y no verifica si hay errores :), y luego el sistema operativo asigna un puerto libre aleatorio por encima de 1024.
Nota 1: Uso "escuchar" entre comillas en todas partes, porque el concepto no es muy claro en el contexto de los sockets UDP. Una vez que haya creado el socket y lo haya vinculado a un puerto, ya sea llamando bind() explícitamente o enviando datos y permitiendo que el sistema operativo lo vincule a un puerto, puede recibir datos desde cualquier lugar a través de él. No es necesario escuchar() o aceptar() llamadas.
Nota 2: Usted dice que UdpSocket :: Open() llama a connect(), pero eso no tiene mucho sentido - connect() hace muy poco para sockets UDP - simplemente establece una dirección predeterminada para que pueda usar send() en lugar de sendto() y no especifica la dirección en cada envío.
Espero que aclare las cosas.
Editar para tratar el comentario de OP: Nunca he usado esta biblioteca, pero según sus
UdpSocket documentation hay 4 sobrecargas del método Bind() y cada una de ellas acepta el puerto de alguna manera. Ninguno de ellos funciona para ti?
¿Está llamando a Bind() y Open() en el mismo objeto UdpSocket o dos objetos diferentes? –
Llama a Bind(), y luego a Open(), y luego a Send() utilizando el mismo objeto instanciado. – cedgriss