servidor - Cómo crear un socket TCP conectado utilizando C a un puerto predefinido
sockets java (4)
Tengo una pregunta muy simple. Quiero probar si un puerto en particular está actualmente en uso o no. Para esto, quiero vincular un socket TCP al puerto, si la conexión es rechazada significa que el puerto está en uso y si no significa que el puerto es libre.
¿Puede alguien decirme cómo puedo escribir el código del socket TCP en C? Estoy en una plataforma solaris.
Sé que es muy básico. Pero aprecio tu ayuda. Gracias por adelantado.
Depende ligeramente de exactamente lo que intentas probar.
El uso de bind()
en la forma sugerida por joelc le dirá si el puerto está abierto en cualquier interfaz en su máquina. Aunque para ser minucioso, no solo deberías comprobar el valor de retorno de bind()
, sino también comprobar errno == EADDRINUSE
.
es decir. (modificación del código de joelc)
if(bind(socket, (struct sockaddr *)&sin,sizeof(struct sockaddr_in) ) == -1)
{
if( errno == EADDRINUSE )
{
// handle port already open case
}
else
{
// handle other errors
}
}
Al cambiar la dirección utilizada en la línea: ej.
sin.sin_addr.s_addr = inet_addr("192.168.1.1");
... puede probar si un puerto está disponible en una interfaz específica.
Tenga en cuenta que esta no es una prueba perfecta para el estado del puerto. Si otro proceso tenía el puerto abierto y finalizado antes de cerrar con gracia el puerto (es decir, antes de llamar a close()
en el socket), entonces generalmente obtendrá el mismo error EADDRINUSE
. (dependiendo de si la opción SO_REUSEADDR se configuró en el socket)
(nota al margen: a menos que su aplicación de prueba se ejecute con suficientes privilegios, no podrá enlazar () a ningún puerto por debajo de 1024)
Como lo sugirió Anonymous, también puedes echarle un vistazo a netstat
. Esto le dará toda la información que puede obtener llamando repetidas veces a bind()
mucho más rápido y sin ninguno de los efectos secundarios (como que no tiene que vincularse realmente a los puertos, lo que los haría inutilizables para cualquier otros procesos). Simplemente llamando a netstat -a --numeric-ports -t
y analizando la salida debería darle todo lo que está buscando.
Sin embargo, un comentario sobre la sugerencia de moogs: llamar a telnet en cada puerto solo le dirá si un socket está escuchando en ese puerto, no si realmente está abierto.
Es posible que desee ver el código fuente de netstat. Creo que también hay un netstat en Solaris.
¿Desea probar si el puerto en particular está actualmente en uso? (y realmente no necesita hacer un programa). Si es así, puedes usar telnet:
puerto de host telnet
Si la conexión falla, no está en uso. Si se conecta y espera tus comentarios, está en uso :)
La función de llamada para vincular devolverá -1 si hay un error. Esto incluye el caso donde la dirección ya está en uso.
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define PORT 12345
int main()
{
struct sockaddr_in addr;
int fd;
fd = socket(AF_INET, SOCK_STREAM, 0);
if(fd == -1)
{
printf("Error opening socket/n");
return -1;
}
addr.sin_port = htons(PORT);
addr.sin_addr.s_addr = 0;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_family = AF_INET;
if(bind(fd, (struct sockaddr *)&addr,sizeof(struct sockaddr_in) ) == -1)
{
printf("Error binding socket/n");
return -1;
}
printf("Successfully bound to port %u/n", PORT);
}