Aller au contenu


Photo
- - - - -

Programmation...............


  • Veuillez vous connecter pour répondre
22 réponses à ce sujet

#11 Seiju

Seiju

    Godlike Member

  • Membres
  • 2 059 messages

Posté 30 avril 2001 - 08:54

Oui c'est normal que ton port ne soit pas libéré automatiquement. Le closesocket se contente d'indiquer au systeme que tu ne te sers plus du port et c'est lui qui s'occupe du reste quand il a le temps. C'est un processus assynchrone donc tu ne peux pas etre sur de pouvoir a nouveau ouvrir le meme port quand tu en as besoin.



Seiju
  • 0

PUBLICITÉ

    Annonces Google

#12 Speedy

Speedy

    Mega Power Member

  • Membres
  • 277 messages

Posté 30 avril 2001 - 08:58

Voila ce que moi j'utilise

void Ftp::CreateListenSocket(unsigned short port, SOCKET *Sckt, int backlog)

//Entrée : Un entier court non signé, un socket et un entier.

//Sortie : Aucune.

//Spécification : Crée un socket d'écoute pour l'envoi et la réception de données.

{

int i;

ulong far ul=1;

bool SockConnected = false;

bool FinDemandee = false;

TIMEVAL t = {0,200};

DWORD dw,bw;

fd_set FdSet;



*Sckt = socket(PF_INET,SOCK_STREAM,0);



if(*Sckt==INVALID_SOCKET)

{

DWORD d = WSAGetLastError();

ThrowWSAE("Impossible de créer le socket");

}



if(ioctlsocket(*Sckt, FIONBIO, &ul)!=0)

{

ThrowWSAE(WSAGetLastError(),"Erreur dans ioctlsocket");

}



if(*Sckt==INVALID_SOCKET)

{

ThrowWSAE(WSAGetLastError(),"Erreur de création du socket");

}



ipAddr.sin_family = AF_INET;

ipAddr.sin_port = htons(port);

ipAddr.sin_addr.s_addr=htons(INADDR_ANY);



//--On ne gére pas les erreurs du bind et du listen car ses erreurs sont du à l'impossibilitée

//--de se connecter.

//--Ceci étant, si l'on ne peut pas se connecter sur un port donné, le changement de port

//--de connexion est fait automatiquement et le fait de gérer les erreur dans le bind

//--et le listen rendrait ceci plus difficile.







bw=bind(*Sckt,(LPSOCKADDR)&ipAddr, sizeof(ipAddr));



dw = listen(*Sckt,backlog);



}





Le 2001-04-30 09:39, Seiju a écrit:

Heuu on est pas au meme niveau, je te parles Socket et tu me parles FTP

Ca n'a rien a voir avec le protocole FTP mais avec la gestion des sockets ton probleme.



A moins que tu n'utilises une lib de fonctions faites par kkun d'autres et que tu ne touches pas toi-même aux sockets. Dans ce cas, il faut voir avec la personne qui a developpé cette lib.



Pour le port libre sur le client, tu n'as rien a faire justement. C'est si tu veux spécifier un port qu'il faut appeler une fonction. Tu te contentes d'appeler la fonction "connect".



En fait tu dois avoir un truc ressemblant a ca :





-----------------------------------------


#include <winsock2.h>





int main(int argc, char* argv[])


{


	SOCKET sockClient;


	struct sockaddr_in addrServ;


	int errCode;


	unsigned int addr;


	struct hostent *hp;


	WORD wVersionRequested;


	WSADATA wsaData;


	int err;





	// Init Winsock


	wVersionRequested = MAKEWORD( WS_VER_HIGH, WS_VER_LOW );


	


	err = WSAStartup( wVersionRequested, &wsaData );


	if ( err != 0 ) {


  /* Tell the user that we could not find a usable */


  /* WinSock DLL.                                  */


  sys_err("Version de Winsock invaliden");


	}


 


	/* Confirm that the WinSock DLL supports 2.2.*/


	/* Note that if the DLL supports versions greater    */


	/* than 2.2 in addition to 2.2, it will still return */


	/* 2.2 in wVersion since that is the version we      */


	/* requested.                                        */


	if ( LOBYTE( wsaData.wVersion ) != WS_VER_LOW ||


      HIBYTE( wsaData.wVersion ) != WS_VER_HIGH ) {


  /* Tell the user that we could not find a usable */


  /* WinSock DLL.                                  */


  WSACleanup( );


  sys_err("Version de Winsock invaliden");


	}





	// Créer socket


	sockClient = socket(AF_INET, SOCK_STREAM, 0);


	if (sockClient == INVALID_SOCKET) {


  sys_err("Erreur création socketn");


	}





	// Position l'adresse et le port du server


	addr = inet_addr("127.0.0.1");


	hp = gethostbyaddr((char *)&addr,4,AF_INET);


	if (hp == NULL) {


  sys_err("Erreur dans l'adresse du servern");


	}





	// Connect socket


	memset(&addrServ, 0, sizeof(addrServ));


	addrServ.sin_family = AF_INET;


	addrServ.sin_port = htons(SERV_PORT);


	memcpy(&(addrServ.sin_addr),hp->h_addr,hp->h_length);


	if (connect(sockClient, (struct sockaddr *)&addrServ, sizeof(addrServ)) != 0) 


	{


  errCode = WSAGetLastError();


  WSACleanup();


  sys_err("Connect error : %dn", errCode);


	}





	// .......


	// ....... Traitement a effectuer pendant la connexion


	// .......





	// Ferme tout


	closesocket(sockClient);





	return 0;


}


---------------------------------------





Seiju





[ Ce Message a été édité par: Seiju le 2001-04-30 09:51 ]


  • 0

#13 Seiju

Seiju

    Godlike Member

  • Membres
  • 2 059 messages

Posté 30 avril 2001 - 09:08

LOL !!

On s'est mal compris !!

Je croyais que tu faisais un CLIENT FTP alors qu'en fait tu fais un SERVEUR FTP !!



Ton code me parrait bien en tout cas, a part un truct qui me parrait bizarre :

ipAddr.sin_addr.s_addr=htons(INADDR_ANY);

essayes ca plutot :

ipAddr.sin_addr.s_addr=INADDR_ANY;



Seiju
  • 0

#14 Speedy

Speedy

    Mega Power Member

  • Membres
  • 277 messages

Posté 30 avril 2001 - 09:10

J'avai déja essayé çà, mais ça change rien

du tout.

Ce qui serait bien, c une fonction qui me donnerai le numéro du premier port libre.

Y'en a une?????
  • 0

#15 Seiju

Seiju

    Godlike Member

  • Membres
  • 2 059 messages

Posté 30 avril 2001 - 09:21

Ce genre de fonction ne te servirait a rien là vu que tu créés un serveur.



Seiju
  • 0

#16 Speedy

Speedy

    Mega Power Member

  • Membres
  • 277 messages

Posté 30 avril 2001 - 09:27

Ba si because :

commande tel que RETR

ordi---------------->ordi

local<--------------distant

réponse à la commande

Aprés avoir envoyé un réponse l'ordi distant

va tenté de se connecter sur un port de l'ordi local



Le pb est dans cette 2éme phase car je

spécifie le port sur lequel l'ordi distant doit se connecter sans savoir si le port est libre ou pas.

ordi<---------------ordi

local distant

envoi données (fichiers)



où inversement

ordi

local-------------->ordi distant







[ Ce Message a été édité par: speedy le 2001-04-30 10:28 ]
  • 0

#17 Seiju

Seiju

    Godlike Member

  • Membres
  • 2 059 messages

Posté 30 avril 2001 - 09:33

Oublies le code de tout a l'heure c'etait pour un CLIENT, pour le SERVEUR ce serait plutot ca :



#include <winsock2.h>





void Server(void *args)


{


	WORD wVersionRequested;


	WSADATA wsaData;


	int err;


	SOCKET sockServ, sockConn;


	struct sockaddr_in addrServ;


	struct sockaddr_in addrConn;


	int errCode, asSize;





	// Init Winsock


	wVersionRequested = MAKEWORD( WS_VER_HIGH, WS_VER_LOW );


 


	err = WSAStartup( wVersionRequested, &wsaData );


	if ( err != 0 ) {


  /* Tell the user that we could not find a usable */


  /* WinSock DLL.                                  */


  sys_err("Version de Winsock invaliden");


	}


 


	/* Confirm that the WinSock DLL supports 2.2.*/


	/* Note that if the DLL supports versions greater    */


	/* than 2.2 in addition to 2.2, it will still return */


	/* 2.2 in wVersion since that is the version we      */


	/* requested.                                        */


 


	if ( LOBYTE( wsaData.wVersion ) != WS_VER_LOW ||


      HIBYTE( wsaData.wVersion ) != WS_VER_HIGH ) {


  /* Tell the user that we could not find a usable */


  /* WinSock DLL.                                  */


  WSACleanup( );


  sys_err("Version de Winsock invaliden");


	}





	// Créer socket


	sockServ = socket(AF_INET, SOCK_STREAM, 0);


	if (sockServ == INVALID_SOCKET)


  sys_err("Erreur création socket");





	// Bind socket


	memset(&addrServ, 0, sizeof(addrServ));


	addrServ.sin_family = AF_INET;


	addrServ.sin_port = htons(SERV_PORT);


	addrServ.sin_addr.S_un.S_addr = INADDR_ANY;


	if (bind(sockServ, (struct sockaddr *)&addrServ, sizeof(addrServ)) != 0) 


	{


  errCode = WSAGetLastError();


  WSACleanup();


  sys_err("Bind error : %dn", errCode);


	}





	// Mise en état d'écoute


	if (listen(sockServ, 5) != 0) 


	{


  errCode = WSAGetLastError();


  WSACleanup();


  sys_err("Listen error : %dn", errCode);


	}





	while (Quitter == FALSE)


	{


  // Attend une connexion


  asSize = sizeof(addrConn);


  memset(&addrConn, 0, asSize);


  sockConn = accept(sockServ, (struct sockaddr*)&addrConn, &asSize);


  affiche_msg("Connexion de %s, port %dn", inet_ntoa(addrConn.sin_addr), htons(addrConn.sin_port));





  // .....


  // ..... Comm avec client


  // .....





  closesocket(sockConn);


	}


	


	// Stop connexion


	closesocket(sockServ);





	Quitter = TRUE;


}



  • 0

#18 Speedy

Speedy

    Mega Power Member

  • Membres
  • 277 messages

Posté 30 avril 2001 - 09:36

Oooooooook

Merci pour tout................

[ Ce Message a été édité par: speedy le 2001-04-30 10:37 ]
  • 0

#19 Seiju

Seiju

    Godlike Member

  • Membres
  • 2 059 messages

Posté 30 avril 2001 - 09:50

J'ai trouvé sur MSDN dans la description de la fonction bind :



"For TCP/IP, if the port is specified as zero, the service provider will assign a unique port to the application with a value between 1024 and 5000. The application can use getsockname after bind to learn the address and the port that has been assigned to it. "



Seiju
  • 0

#20 Speedy

Speedy

    Mega Power Member

  • Membres
  • 277 messages

Posté 30 avril 2001 - 09:52

C vrai, g'av pas fait attention à ça.

Thanks
  • 0