begin process at 2012 05 29 21:20:57
  Trouver un code source :
 
dans
 
Accueil > Forum > 

Archive C/C++

 > 

Archives

 > 

Réseau / Internet

 > 

Problème lors de la fermeture de sockets


Derniers messages déposésPoser une question dans le forum ou lancer une discussion

Problème lors de la fermeture de sockets

mercredi 15 septembre 2004 à 17:38:00 | Problème lors de la fermeture de sockets

malik7934

Hello,

J'ai dans mon programme un socket qui est ouvert et j'envoie d'un client vers un serveur (et vice versa) des infos qui sont traîtées à chaque fois. Si suite à un traitement je'ai pour réponse FALSE, alors un message d'erreur apparaît et le programme est arrêté (j'ai mis à chaque fois {closesocket(m_socket); return FALSE;} en cas d'erreur).

Mon problème: si je veux re-exécuter mon programme avec d'autres données (fichier extérieur), je dois d'abord fermer mon programme, sinon il plante systématiquement. Je suis pratiquement certain que c'est une question de mauvaise fermeture de sockets, pourtant j'ai mis des closesocket à outrance dans tous les coins! Une idée?

HELP!!!

Thanx, Malik7934
mercredi 15 septembre 2004 à 18:38:20 | Re : Problème lors de la fermeture de sockets

Nebula

Membre Club
Tu recrées le socket après l'avoir fermé ou pas ? Parce qu'une fois fermé, le socket est inutilisable...
mercredi 15 septembre 2004 à 19:34:36 | Re : Problème lors de la fermeture de sockets

malik7934

En deux mots, j'ai une fonction ServerListen. Lorsqu'elle est lancée, si j'exécute ClientConnect, une connexion est crée. Ca veut dire un socket. Ca, je le fais au début de mon prog, ensuite j'utilise des fonctions "maison" genre sendfile(name) ou receivefile(name). Lors du traîtement, avant de faire, si besoin, un return FALSE, je fais closesocket(m_socket) systématiquement... et normalement, si je relance le tout (sans fermer le programme donc), je devrais retomber sur ClientConnect et un nouveau socket devrait être créé... mais dès lors, ça plante (soit le prog ne voit pas la nouvelle socket, soit il agit comme si l'ancienne était tjs là, ce qui n'est pas le cas).

En fait, je me demandais surtout s'il y a une systématique pour la fermeture des sockets? Comme on le fait toujours avec un fichier texte (cf closehandle).

J'suis plus clair là?
mercredi 15 septembre 2004 à 20:09:12 | Re : Problème lors de la fermeture de sockets

Nebula

Membre Club
Pas vraiment plus clair...

Un socket doit être fermé quand tu n'en as plus besoin (généralement à la déconnexion d'un client, un seul closesocket suffit), pas après chaque opération... Çà vient peut-être d'une erreur dans la manière dont tu passes le handle du nouveau socket à ClientConnect, ou de la manière dont tu as géré les déconnexions, ou de n'importe quoi d'autre, je ne sais pas :-/

Enfin sans code, c'est difficile à déterminer...
mercredi 15 septembre 2004 à 20:55:36 | Re : Problème lors de la fermeture de sockets

malik7934

ok, je regarderai demain si j'arrive à mettre du code explicite (mon code fait passé 1000 lignes, alors je peux pas tout mettre comme ça),

thanx, Malik7934
jeudi 16 septembre 2004 à 08:38:58 | Re : Problème lors de la fermeture de sockets

malik7934

Hello,

me revoilà avec du code cette fois!

Au départ, j'ai un serveur qui se met en écoute si on appuie sur le bouton "LISTEN":

case IDC_LISTEN:
char tBuff[6];
int PORT;
GetDlgItemText(hWndconfp,IDC_PORT,tBuff,5);
PORT = atoi(tBuff);
ServerListen(PORT);

La fonction ServerListen est des plus standard: Initialisation de WINSOCK, création du socket, binding du socket et écoute sur le socket.

Ensuite, un client vient se connecter (même blabla: Initialisation de WINSOCK, création du socket, connection au serveur).

Ensuite, je commence à avoir des problème: je fais des échanges de fichiers avec des fonctions genre

if (!csSendFile("C:/WINDOWS/Temp/hello.txt")) {closesocket(m_socket);return FALSE;}

et tout va très bien s'il n'y a pas d'erreur (à chaque étape, des traîtements ont lieu et retournent True ou False). Par contre, s'il y a un False, mon prog plante! Ca veut dire qu'en cas d'erreur, il est interrompu et si je le re-exécute sans le fermer et l'ouvrir à nouveau, il ne fonctionnera plus. Sûr que c'est une histoire de fermetur/ouverture de socket...
jeudi 16 septembre 2004 à 11:16:52 | Re : Problème lors de la fermeture de sockets

aardman

Membre Club
Salut,
Si tu fermes ton socket avec closesocket() le status du port va etre WAIT (TIME-WAIT ou CLOSE-WAIT) car le socket n'a pas été fermé proprement. Au bout de quelques minutes le port perd ce status et peut etre réutilisé (Tu peux faire un netstat pour le voir par toi meme).
Normalement on utilise shutdown() suivit de closesocket() pour fermer une connexion proprement.

Regarde du coté de setsockopt() avec l'option SO_REUSEADDR, qui permet de re-binder sur un port sans avoir a attendre plusieurs minutes.
jeudi 16 septembre 2004 à 13:26:44 | Re : Problème lors de la fermeture de sockets

Nebula

Membre Club
> La fonction ServerListen est des plus standard: Initialisation de WINSOCK, création du socket, binding du socket et écoute sur le socket.

> Ensuite, un client vient se connecter (même blabla: Initialisation de WINSOCK, création du socket, connection au serveur).

Si je te suis tu initialises Winsock plusieurs fois dans l'appli... Il vaut mieux éviter à moins que tu ne le fasses dans différents threads.

Sinon y'a rien de suspect dans ton code à part le manque de shutdown pointé par aardman, c'est peut être dans ton imbrication de return qu'à un moment y'a un truc qui va pas...

Et j'ai un doute en relisant, tu appelles WSACleanup plusieurs fois aussi ? Car un seul appel suffit pour que tous les sockets du thread courant soient inutilisables...
vendredi 17 septembre 2004 à 11:29:59 | Re : Problème lors de la fermeture de sockets

malik7934

Hello!

Je te mets mon code (c'est un patchwork de sources trouvées ici, j'avoue avoir pas trop pigé).

D'abord les fonctions:

#include <winsock2.h> // Socket
#pragma comment(lib,"WS2_32.lib") // Librairie Associé au Socket

#define WM_SOCKET WM_USER+100
int ClientConnect(char *IP,int PORT);
SOCKET m_socket;
SOCKET AcceptSocket;
sockaddr_in clientService;
//BOOL csGet();
//BOOL csSend();


// ###############################################################
// ***********
// *********** Connection du client
// ***********
// ###############################################################

BOOL ClientConnect(char *IP,int PORT)
{
// Initialize Winsock.
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != NO_ERROR)
{

WSACleanup(); return FALSE;

}

//Create a socket.
m_socket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
if (m_socket == INVALID_SOCKET)
{
WSACleanup(); return FALSE;
}

// Connect to a server.
clientService.sin_family = AF_INET;
clientService.sin_addr.s_addr = inet_addr(IP);
clientService.sin_port = htons(PORT);

if (connect(m_socket,(SOCKADDR*) &clientService,sizeof(clientService)) == SOCKET_ERROR)
{
WSACleanup();
return FALSE;
}
else
{
return TRUE;
}

//Initialisation de WSAAsyncSelect
if(WSAAsyncSelect(m_socket, NULL, WM_SOCKET, FD_READ|FD_WRITE|FD_CONNECT) == SOCKET_ERROR)
{
WSACleanup(); return FALSE;
}

return TRUE;
}

// ###############################################################
// ***********
// *********** Envoi d'un char
// ***********
// ###############################################################

BOOL csSend(char* szData, DWORD msgSize)
{
send(m_socket,szData,msgSize,0);
return TRUE;
}

// ###############################################################
// ***********
// *********** Envoi d'un fichier
// ***********
// ###############################################################

BOOL csSendFile(char* fileName)
{
FILE* fich;
char *buffer;
int TailleFichier1;
DWORD dwFileSize=0;
HANDLE hSrcFile = INVALID_HANDLE_VALUE;

hSrcFile = CreateFile(fileName,GENERIC_READ,FILE_SHARE_READ,NULL,
OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if(hSrcFile == INVALID_HANDLE_VALUE)
{
CloseHandle(hSrcFile);
return FALSE;
}

dwFileSize = GetFileSize(hSrcFile,NULL) + 1;
CloseHandle(hSrcFile);

if ((buffer=(char *)malloc(dwFileSize))==NULL) return FALSE;
if ((fich=fopen(fileName,"rb"))==NULL) return FALSE;

TailleFichier1=fread(buffer,1,10000,fich);
if (send(m_socket,buffer,TailleFichier1,0)<0) return FALSE;
fclose(fich);
free(buffer);

return TRUE;
}

// ###############################################################
// ***********
// *********** Réception d'un buffer
// ***********
// ###############################################################

BOOL csGet(char* getData)
{
ZeroMemory(getData,10000);
recv(m_socket,getData,10000,0);
return true;
}

// ###############################################################
// ***********
// *********** Réception d'un fichier
// ***********
// ###############################################################

BOOL csGetFile(char* fileName)
{
FILE* fich;
char *buffer; // buffer memoire, va recevoir données du serveur
int TailleFichier; // Taille Fichier

if ((fich=fopen(fileName,"w"))==NULL) {return FALSE;}
if ((buffer=(char *)malloc(10000))==NULL) {return FALSE;}
if ((TailleFichier=recv(m_socket,buffer,10000,0))<0) {return FALSE;}
fwrite(buffer,1,TailleFichier,fich); // Ecriture dans FICHIER
fclose(fich);
free(buffer); // Libère mémoire

return TRUE;
}

// ###############################################################
// ***********
// *********** Attente d'un client
// ***********
// ###############################################################

BOOL ServerListen(int PORT)
{
//Initialisation de WINSOCK
WSADATA wsaData;

//int optval = 0x200;

int iResult = WSAStartup(MAKEWORD(2,2),&wsaData);
if(iResult != NO_ERROR)
{
WSACleanup();
return FALSE;
}

//Creation du socket
m_socket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(m_socket == INVALID_SOCKET)
{
WSACleanup();
return FALSE;
}

//Binding du socket
sockaddr_in service;
service.sin_family = AF_INET;
service.sin_addr.S_un.S_addr = INADDR_ANY;
service.sin_port = htons(PORT);

iResult = bind(m_socket,(SOCKADDR*) &service, sizeof(service));
if(iResult == SOCKET_ERROR)
{
closesocket(m_socket);
return FALSE;
}

//Ecoute sur le socket
if (listen(m_socket,0) == SOCKET_ERROR) // J'ai remplacé le 0 par un 1


// setsockopt(m_socket, SOL_SOCKET, SO_RCVTIMEO, (char*)&optval, sizeof(optval));
// setsockopt(m_socket, SOL_SOCKET, SO_SNDTIMEO, (char*)&optval, sizeof(optval));

if(WSAAsyncSelect(m_socket, NULL, WM_SOCKET, FD_ACCEPT|FD_CLOSE|FD_READ|FD_WRITE) == SOCKET_ERROR)
{
WSACleanup();
return FALSE;
}

return TRUE;
}


Dans mon prog, je n'ai qu'un seul client, du coup il me semble qu'il ne vient se connecter qu'une fois (ClientConnect(..))

Ensuite, dans mon programme principale, je fais des appels genre:

if (!csSendFile("file.txt")) {return FALSE;}


et le "return false" me fait sortir de la où je suis et m'envoie à

...
case IDC_COMP:
if(computeS(hWndconf)){
MessageBox(hWndconf,"GHIProof successfully executed","Verifier: Success",MB_OK);
}
else{
MessageBox(hWndconf,"GHIProof aborted: an error occurs","Verifier: Error",MB_OK);
}
closesocket(m_socket);
return TRUE;


En fait, que ce soit True ou False, lorsque j'en ai fini avec mon client (computeS), mon socket est fermé!

Tu penses quoi de mon code (faut encore que je tienne compte de la remarque de aardman) ???
vendredi 17 septembre 2004 à 18:17:53 | Re : Problème lors de la fermeture de sockets

Nebula

Membre Club
Pas de boucle dans ServerListen, elle ne peut donc servir qu'une fois...

Pourquoi tous ces WSAStartup() ? Appelle le dans WinMain() ou main(), mais pas à chaque fois que tu as envie d'utiliser un socket ! Même remarque pour WSACLeanup, à partir d'un seul appel tous les sockets du programme sont détruits => ne l'appelle qu'avant de sortir du programme.

if(hSrcFile == INVALID_HANDLE_VALUE)
{
CloseHandle(hSrcFile);
return FALSE;
}
===> Inutile de fermer un handle invalide !

Sinon, pour en finir et sans vouloir être mesquin, çà se voit que c'est un patchwork de source... C'est assez décousu ! Regarde donc à cette adresse, et fais ton propre code (c'est plus facile pour commencer, que de reprendre des codes existants) : http://c.developpez.com/WalrusSock/

Y'a sûrement d'autres erreurs, j'ai juste survolé... Bon courage !

1 2

Cette discussion est classée dans : problème, programme, fermeture, socket, sockets


Répondre à ce message

Sujets en rapport avec ce message

Problème UDP [ par ToToL ] BonjoursJe me suis attaquer il y a peut de temps au socket UDP ( aparament plus rapide que le tcp ) et j'ai un petit souci : je n'arrive pas ds le mem problème de gestion de plusieurs clients [ par joeblack59 ] j'ai téléchargé un programme sur ce site qui permet d'envoyer des messages entre un client et un serveur sous Windows.Ce programme est celui à la page Problème de fermeture de fenêtre principale [ par tigerskin ] Bonjour !!J'ai un problème avec un programme que j'ai réalisé : tout le déroulement de mon programme se passe bien mais lorsque je quitte ma fenêtre p [C++ Builder] Problème EAccessViolation a la fermeture du programme [ par Sat83 ] Bonjour!Je viens réclamer votre aide car je suis face a un problème dont je ne comprend pas la cause.J'ai une exception EAccessViolation a la fermetur Vider une socket [ par Dryko ] Bonjour, Je travaille sur un projet de serveur et client UDP. J'utilise les sockets de windows avec les fonctions recvfrom et sendto entre autres.Du c Appeler programme C++ avec des paramétres via PHP [ par saissi_hssine ] Bonjour ,J'ai un problème qui m'as bloqué ça fait 3 jours maintenant, voici mon problème:j'ai un fichier test.cpp ou il y a que le mainint main (int a socket UDP - récupérer réponse [ par _Xav_ ] Hello tout le monde, voici mon problème:J'ai écris une class dns avec laquelle j'envoie des paquets (en udp) et j'aimerais recevoir les réponses faite Problème de socket [ par MattU ] J'ai un petit soucis avec les CSocket!! Pour info, je developpe sur Visual Studio 2008 et j'aimerai utiliser la méthode des CSocket plutot que leurs e courbe en c [ par jiHANE886 ] Bonjour,J'ai un programme rédigé en C qui prend une série de points dans un fichier .dat et détermine l'équation de la courbe qui approxime le mieux c Problème de boucle for [ par blue01 ] Bonjour tout le monde,    je fais actuellement un programme pour résoudre et générer des sudoku pour me faire la main.Mon compilateur compile en c++ (


Nos sponsors


Sondage...

CalendriCode

Mai 2012
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

Consulter la suite du CalendriCode

A découvrir



 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 1,357 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales