Article View: es.comp.os.linux.programacion
Article #1269Re: Usar un socket UDP con origen y destino
From: Oscar Garcia
Date: Wed, 28 Dec 2005 12:10
Date: Wed, 28 Dec 2005 12:10
124 lines
6890 bytes
6890 bytes
El Wed, 28 Dec 2005 12:07:13 +0100, Count Zero <mark@l3jane.net> escribi�: >> No hombre. Con socket creas las estructuras asociadas al socket que >> est�s creando. Para conectarte a una m�quina remota no necesitas un >> "connect", ni siquiera un "bind" (que ser�a necesario en caso de que >> no quieras que el SO elija por t� ip y puerto local). > >Te recurdo que me intento es 'emular' un protocolo orientado a conexi�n. >A�n as� de tu comentario deduzco que con un bind() y luego un connect() >puedo elegir direcci�n y puerto local y remotos tanto en UDP como en >TCP. Se puede as�? S�, pero piensa as� s�lo en el extremo cliente si lo deseas, en el lado del servidor no debes pensar as�. Cuando un cliente va a transmitir datos a un servidor, �ste se dedicar� a enviarlos a un puerto destino usando siempre el mismo puerto fuente. Las parejas puerto/ip fuente y puerto/ip destino son las que definen una conexi�n �nica. En tu implementaci�n debes pensar en la parte del servidor debes crear un socket que escuche en un puerto local, pero que acepte cualquier puerto remoto ya que en caso contrario no podr�s aceptar conexiones "nuevas". Como tienes el socket UDP escuchando en un puerto local aceptando cualquier puerto remoto no te dejar� posteriormente hacer un connect a un socket nuevo sin cerrar previamente el anterior. En este caso debes implementar en tu software de servidor un send y recv que ponga autom�ticamente los datos remotos y locales en cada paquete que envies con recvfrom y sendto. Hay que tener especial cuidado al aceptar paquetes de un mismo host con puerto origen distinto a una conexi�n establecida (tu software debe preveer eso y considerarlo como un intento de conexi�n nueva). >> Lo normal es enviar un paquete UDP solicitando la conexi�n y que tu >> aplicaci�n la permita o la rechace no sin antes pasarle mediante un >> callback a la aplicaci�n interesada que dicha conexi�n se ha >> producido. > >(Supongo que con 'callback' indicas algo tipo el SYN+ACK del TCP, que es >similar a lo que yo hago.) > >Precisamente en este punto es donde tengo problemas: > >Una vez el servidor ha acceptado (y notificado al cliente) la >'conexi�n', el cliente ya puede transmitir y recibir sin problemas, ya >que el socket ya est� "conectado" al servidor. El cliente s�, pero como acabo de decirte, el servidor NO. >Pero el servidor en ese momento s�lo dispone de un socket UDP associado >localmente mediante bind() que, aqu� mi problema, RECIBE DE QUALQUIER >CLIENTE. Por lo tanto necesito un m�todo para distinguir diversos >clientes (flujos), y como muy bien apunta I�aki, UDP no tiene concepto >de flujo por lo que me las debo apa�ar yo. > >Mi idea era intentar emular el accept() de TCP m�s o menos as�: Quiz� no entiendas bien como trabaja la capa de red en TCP y por eso no llegas a entender la complejidad de lo que deseas hacer. >- - Una vez acceptada la conexi�n el servidor creo un nuevo socket >- - Con bind() lo associo al puerto local donde doy servicio (que �s por >d�nde el cliente me enviar� datagramas). >- - Con connect() lo associo al cliente que ha pedido la conexi�n. Aunque >UDP no �s orientado, eso me garantiza que S�LO RECIBIR� DATAGRAMAS DE >ESE CLIENTE (man dixit) Por lo pronto espero que entiendas porqu� te dice "address already in use". No puedes hacer ni un bind ni un connect a un puerto local ya usado por un servidor ya que se supone que espera datos de "cualquier" puerto remoto (para poder aceptar conexiones nuevas de cualquier equipo remoto). Eso deja en uso dicho puerto local y no podr�s fijar con bind ning�n otro socket a dicho puerto. >> Debes crearte una estructura a nivel de tu aplicaci�n que guarde todos >> los valores de ambos extremos una vez que se haya terminado el proceso >> de establecimiento de conexi�n. Esto implica que todo lo tendr�s >> previamente almacenado en memoria (los sockaddr_in del otro extremo, >> por ejemplo). > >Ya tengo esa estructura, s�lo que hasta el momento intentaba evitar >tener que almacenar esa informaci�n, pero veo que ya va siendo hora de >que toque de pies al suelo y lo haga. Espero que ahora entiendas que es NECESARIO usarla. >> Entonces estar�as usando TCP y no UDP. > >No, la llamada socket() especifica el tipo de protocolo via SOCK_DGRAM o >SOCK_STREAM, connect() y bind() no hacen nada al respecto. (Mira las >p�ginas de man) Hasta ahora hab�a usado bind en un UDP, pero no connect. >> A ver. Eso es posiblemente porque has hecho un bind y has ocupado un >> puerto local y/o ip local para enviar datos, de modo que no se puede >> usar ese mismo puerto para enviar m�s datos. > >Ten�a entendido (quiz� me equivoco) que el sistema identifica una >conexi�n/socket por la tupla >direcci�n-local:puerto-local/direcci�n-remota:puerto-remoto, por lo que >cre�a que podr�a hacer el bind() a�n y ya tener un socket en ese puerto, >pero se queja con el error "Address already in use", por lo que debo >destimar este enfoque. Exacto, y esa es la idea, pero al crear el socket escuchando en un puerto.. est�s "fijando" un socket a un puerto local y cualquier ip local y puerto/ip remoto, de modo que cualquier intento de fijar de nuevo otro socket a dicho puerto local es infructuoso. Espero que hayas entendido la complejidad real del servidor que intentas crear no puede reducirse usando connect y bind como pensabas. Un saludo. -- �scar Javier Garc�a Baudet LinaresDigital http://redstar.linaresdigital.com/
Technical Details
Message-ID:
<1ut4r11c0fshajdq0qbojjefo4oo5eslt2@4ax.com>Path:
arc1-ca.pugleaf.net!g2news1.google.com!news1.google.com!proxad.net!213.200.89.82.MISMATCH!tiscali!newsfeed1.ip.tiscali.net!border2.nntp.ams.giganews.com!nntp.giganews.com!news.musoftware.de!news-15.escomposlinux.org!cernicalo.escomposlinux.org!escomposlinux.org!not-for-mailReferences:
<1135696121.15210.14.camel@localhost.localdomain> <5023r1dmnimoopu4cmtg10f8v3qtp4n0if@4ax.com> <dotrl1$i1m$1@news-3.escomposlinux.org>Show Full Headers
Complete Article Headers
X-Google-Thread: f86c8,e630809bf4f9f23d X-Google-Attributes: gidf86c8,public X-Google-Language: SPANISH,ASCII Path: arc1-ca.pugleaf.net!g2news1.google.com!news1.google.com!proxad.net!213.200.89.82.MISMATCH!tiscali!newsfeed1.ip.tiscali.net!border2.nntp.ams.giganews.com!nntp.giganews.com!news.musoftware.de!news-15.escomposlinux.org!cernicalo.escomposlinux.org!escomposlinux.org!not-for-mail From: Oscar Garcia <redstarQUITARSPAM23@terra.es> Newsgroups: es.comp.os.linux.programacion Subject: Re: Usar un socket UDP con origen y destino Date: Wed, 28 Dec 2005 13:10:50 +0100 Organization: Ecolnet Lines: 124 Message-ID: <1ut4r11c0fshajdq0qbojjefo4oo5eslt2@4ax.com> References: <1135696121.15210.14.camel@localhost.localdomain> <5023r1dmnimoopu4cmtg10f8v3qtp4n0if@4ax.com> <dotrl1$i1m$1@news-3.escomposlinux.org> NNTP-Posting-Host: 62-14-93-178.inversas.jazztel.es Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit X-Trace: cormoran.emeteo.local 1135771846 12371 62.14.93.178 (28 Dec 2005 12:10:46 GMT) X-Complaints-To: emeteo@escomposlinux.org NNTP-Posting-Date: Wed, 28 Dec 2005 12:10:46 +0000 (UTC) X-Newsreader: Forte Free Agent 2.0/32.652