2009-04-12 19 views
8

He intentado lo siguiente:listen() sin llamar a bind()

int sockfd = socket(...); 
listen(sockfd, 10); 
accept(sockfd, ...); 

Ninguna de las llamadas fallidas, y el programa acaba de comenzar el bloqueo como si hubiera llamado a bind(). ¿Qué pasará en este caso? ¿Será simplemente imposible recibir una conexión, ya que no tiene una dirección o puerto local? ¿O se le asignó implícitamente una dirección y un puerto locales, y ahora está escuchando sobre ellos? Si es así, ¿cómo puedo recuperar cuáles son?

Respuesta

10

Las llamadas están trabajando, pero ya que no se unió el zócalo de forma explícita, el sistema operativo o biblioteca del sistema asigna implícitamente un puerto y enlace predeterminado para usted (exactamente el mismo que cuando se llama a connect(2) sin llamar primero bind(2)). Además, ya que preguntaste sobre las cosas del TCP anteriormente, supongo que estás hablando de enchufes de Internet aquí.

Averiguar a qué nombre el sistema operativo enlaza el sistema operativo varía, por lo que tendrá que buscar su sistema operativo específico, pero la mayoría de los sistemas operativos proporcionan una herramienta netstat o similar que puede usar para consultar qué aplicaciones están escuchando en qué puertos.,

Como John menciona en un comentario, puede usar getsockname(2) para encontrar el nombre de un socket encuadernado. Aquí está un ejemplo corto:

// ... 

// Create socket and set it to listen (we ignore error handling for brevity) 
int sock = socket(AF_INET, SOCK_STREAM, 0); 
listen(sock, 10); 

// Sometime later we want to know what port and IP our socket is listening on 
socklen_t addr_size = sizeof(struct sockaddr_in); 
struck sockaddr_in addr; 
getsockname(sock, (struct sockaddr *)&addr, &addr_size); 

addr contendrá ahora la dirección IP y el puerto al que está escuchando en toma.

+0

La llamada getsockname() le dará la dirección/puerto que asignó el sistema operativo. –

+0

Buen punto, John ... Agregaré un código de ejemplo. –

0

Sospecho que nunca obtendrás una conexión. Puede verificar si hay un nuevo socket escuchando haciendo el equivalente de "netstat -an" en su sistema operativo antes y después de ejecutar el programa.

he intentado lo mismo en C#:

Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
socket.Listen(1); 
socket.Accept(); 

consigo una excepción en la segunda línea de la que me informa de una manera indirecta de que se requiere un aprieto. Es, por supuesto, funciona bien con:

Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
socket.Bind(new IPEndPoint(IPAddress.Loopback, 4567)); 
socket.Listen(1); 
socket.Accept(); 

Probé con un socket UDP y así mismo, Windows no es feliz en la Escuchar llaman a menos que una unión se ha hecho. Dado que las llamadas de socket .Net son simplemente envoltorios alrededor de Winsock, este comportamiento es probable que sea el mismo para todas las bibliotecas derivadas de Winsock en Windows.

2

Como mencionan otros, el sistema operativo asignará un puerto si no enlaza() uno. Puede usar la llamada getsockname() después de escuchar() para ver qué dirección/puerto están asignados. Entonces, si comunicó esa dirección/puerto a un cliente, podría conectarse.

Por lo tanto, tiene sentido que esto funcione. Podrías escribir un programa donde esto fuera algo interesante de hacer.

Cuestiones relacionadas