 |
Club Builder Foro de C++Builder en español
|
| Ver tema anterior :: Ver tema siguiente |
| Autor |
Mensaje |
Perico Invitado
|
Publicado: Vie 17 Jun, 2005 8:12 pm Asunto: Lieración de puertos (pregunta larga) |
|
|
hola a todos,
estoy haciendo un scaneador de puertos remotos (no peneis mal), bueno como decia, es escaneador funciona de maravilla, lo que pasa es lo siguiente:
como ejemplo:
voy a escanear el puerto 80 de la IP 5.5.5.5 cada 1 segundo.
hago un bucle for y listo, me dice todo el rato que el puerto esta abierto... pero... llega un momento en el que me dice todo el rato que esta cerrado, cosa que es falsa ya que si reinicio mi aplicación, todo funciona correctamete y me dice que que el puerto 80 esta abierto... (asi hasta que otra vez me dice que esta cerrado).
He llegado a la conclusión de que el sistema operativo le indica a mi programa que puerto LOCAL ha de utilizar como comunicación con el puerto remoto 80 de la IP 5.5.5.5 cada vez que quiero chequear el puerto 80.
Haciendo unas pruebas, he visto que la asignación de puertos LOCALES para comunicación con el puerto 80 remoto se van asignando correlativamente, de tal manera que al iniciar mi aplicación, el primer puerto LOCAL es el número de puerto siquiente al último utilizado la ultima vez que se ejecuto la aplicación, y cuando llega al 5000 es como si volviera a empezar desde el que empezó, pero justamente es cuando empieza a decir que el puerto 80 de la máquina remota esta cerrado (cosa que es falsa).
Creo que el problema está en que una vez utilizado un puerto LOCAL ya no puede volver a ser utilizado de nuevo excepto si cerramos la aplicación.
El tema esta en que debe haber una manera de dejar libre un puerto después de haberlo utilizado.
He probado a asignar los puertos yo mismo desde el 1200 hasta el 65000 y me va bién en todo momento excepto cuando ya ha dado la vuelta (tenqo puesto que si puerto>=65000 puerto=1200)
He utilizado la función closesocket(puerto); y la cosa mejora ya que aun despues de haber dado la vuelta de los 65000 algunos puertos dicen que el 80 del remoto esta abierto (cosa verdadera) y otros puertos LOCALES dicen que esta cerrado (cosa falsa).
Por que pasa esto?
he intentado esperar tiempo por los puertos LOCALES pero creo que no es cuestion de tiempo.
Que solución le veis?
He pensado que una solución seria hacer un programa externo, utilizarlo, reiniciarlo (para tener los puertos otra vez disponibles) y asi, pero me parece una idea muy engorrosa y poco elegante.
esta es la función que utilizo:
| Código: |
void __fastcall TForm1::escanear(String IP,int port)
{
int sock;
struct sockaddr_in cliente;
struct servent *Descripcion;
struct hostent *lookup;
unsigned long addr;
int puerto;
//argv[1] es IP
if (addr=inet_addr(IP.c_str())==-1)
{
Memo1->Lines->Add("No se pudo encontrar " + IP);
exit(-11);
}
if ((lookup = gethostbyaddr((char *) &addr, sizeof(long), AF_INET)) !=NULL)
Memo1->Lines->Add("Escaneando a: " + (String)lookup->h_name);
else
Memo1->Lines->Add("Escaneando a " + IP);
for(puerto=port;puerto<=port;puerto++)
{
if ((sock=socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
Memo1->Lines->Add ("Error al crear Socket.\n");
exit(-1);
}
cliente.sin_family = AF_INET;
cliente.sin_addr.s_addr = inet_addr(IP.c_str());
cliente.sin_port = htons(puerto);
bzero(&(cliente.sin_zero), 8);
Descripcion=getservbyport(htons(puerto), "tcp");
if ((connect(sock, (struct sockaddr*)&cliente, sizeof(cliente))) > -1)
Memo1->Lines->Add("Puerto " + IntToStr(puerto)+ " puerto: "+ IntToStr(Descripcion->s_port));// +" "+ (String)Descripcion + " " + Descripcion->s_name);
closesocket(sock);
contathread++;
Label1->Caption=contathread;
Application->ProcessMessages();
}
}
|
|
|
| Volver arriba |
|
 |
Cesar C. Salazar Gonzalez Master


Registrado: 01 Oct 2002Mensajes: 2155Ubicación: San Cristóbal de Las Casas, Chiapas
|
Publicado: Vie 17 Jun, 2005 8:21 pm Asunto: |
|
|
despues del CloseSock
usa la siguiente sentencia
| Código: |
closesocket(sock);
::WSACleanup(); |
Con esto cierras, y liberas el socket, usado por tu aplicacion. _________________
 |
|
| Volver arriba |
|
 |
Perico Invitado
|
Publicado: Vie 17 Jun, 2005 11:11 pm Asunto: |
|
|
Hola César
que alegria oirte!
bueno la verdad es que he probado lo que me has dicho pero me da un el error "External exception EEFFACE"
lo he puesto según tu me has dicho en mi código...
no se si a ti te funciona
Vemos que yo intento hacer un chequeo del puerrto 80 de mi router dos veces con el mismo puerto LOCAL y no me deja. |
|
| Volver arriba |
|
 |
Perico Invitado
|
Publicado: Mar 21 Jun, 2005 10:07 am Asunto: |
|
|
hola,
he encontrado esto, si alguien lo prueba que diga los resultados por favor
| Código: |
int sockPort=port;
int opt=1;
BOOL yes = true;
if (setsockopt(sockPort, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(BOOL)) < 0)
ShowMessage("mal");
|
|
|
| Volver arriba |
|
 |
Perico Invitado
|
Publicado: Jue 23 Jun, 2005 9:40 am Asunto: |
|
|
Hola de nuevo
mirando en internet he visto esto, lo que pasa es que no se ni lo que es, no se como empezar, a alguien le suena????
se supone que cierra un puerto que esta "listening" no?
WSAAsyncSelect ((SOCKET)Socket->SocketHandle,
Handle,WM_FD_CLOSE, FD_CLOSE);
Gracias |
|
| Volver arriba |
|
 |
Perico Invitado
|
Publicado: Vie 24 Jun, 2005 7:12 pm Asunto: |
|
|
hola de nuevo
espero no parecer pesado, solo quiero decir que ya encontré la solución al problema (al menos las pruebas que he hecho han salido bién)
| Código: |
int port=3010; //por ejemplo...
IdTCPClient1->Host = Edit3->Text;
IdTCPClient1->Port = port;
/* bind local ip/port */
//IdTCPClient1->BoundIP = Edit3->Text;
//IdTCPClient1->BoundPort = StrToInt(Edit5->Text);// 3011;
try
{
IdTCPClient1->Connect(1000);
}
catch(...)
{
Memo1->Lines->Add("No se abre el puerto: " + IntToStr(port));
}
Application->ProcessMessages(); |
y en el OnConnect del IdTcpClient...
| Código: | void __fastcall TForm1::IdTCPClient1Connected(TObject *Sender)
{
Memo1->Lines->Add("Puerto abierto: " + IntToStr(IdTCPClient1->Port));
//IdTCPClient1->DisconnectSocket();
IdTCPClient1->Disconnect(); //esta es la buena
} |
de esta manera los puertos los va asignando el S.O y al terminar la conexion pues se desconecta el Socket.
Antes con el TCPSocket, también iva bién, solo que cuando al S.O. se le acaban los puertos, decia que ya estaba ocupado al intentar el connect(), y el problema es que no sabia como se desconectaba un socket, pero parece que el componente IdTCPClient ya ho hace todo el solo al decirle Disconnect();
Por favor si estoy haciendo algo que no esté bién decidmelo.
Gracias y espero que os sirva de algo el código. |
|
| Volver arriba |
|
 |
|
|
No puedes publicar temas nuevos en este foro No puedes responder a temas en este foro No puedes editar tus mensajes en este foro No puedes borrar tus mensajes en este foro No puedes votar en las encuestas de este foro
|
© 2002–2026 Club Builder · Funciona con phpBB.
|