Besoin d'aide pour connection multi socket

Signaler
Messages postés
28
Date d'inscription
samedi 21 juin 2003
Statut
Membre
Dernière intervention
23 mai 2004
-
Messages postés
28
Date d'inscription
samedi 21 juin 2003
Statut
Membre
Dernière intervention
23 mai 2004
-
j'ai developpe un petit programme de chat sur visual C++ 6.0 a partir d'un programme existant mais ne gerant que 2 connections.
mon but etait de l'etendre a un plus grand nombres de connections mais j'ai un probleme au point de vue des sockets . les 2 premieres fenetres peuvent se connecter ensemble mais la troisieme ne peut communiquer avec personne. les sockets pour cette dernieres sont pourtant bien creer et initialiser mais le serveur ne veut pas les utiliser.

pouvez vous e dire si j'ai oublie quelque chose ou si j'ai fait une erreur quelque part.
merci d'avance pour l'aide car je n'arrive pas à me debloquer tout seul.

7 réponses

Messages postés
1905
Date d'inscription
mercredi 22 janvier 2003
Statut
Membre
Dernière intervention
17 septembre 2012
2
Salut,
Comment veux tu qu'on sache si tu as oublié quelque chose ou si tu as fait une erreur quelque part si tu nous donne pas le bout de code qui gere les sockets ?
Messages postés
28
Date d'inscription
samedi 21 juin 2003
Statut
Membre
Dernière intervention
23 mai 2004

excuser l'oubli je n'avais pas realiser

voici le fichier ReseauDlg.h

// ReseauDlg.h : header file
//

#if !defined(AFX_RESEAUDLG_H__DA3A9147_2BEA_11D4_8BEE_00201854D64E__INCLUDED_)
#define AFX_RESEAUDLG_H__DA3A9147_2BEA_11D4_8BEE_00201854D64E__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "ClasseSocket.h"

/////////////////////////////////////////////////////////////////////////////
// CReseauDlg dialog

class CReseauDlg : public CDialog
{
// Construction

public:
void OnConnect();
void OnSend();
void OnReceive();private:
bool m_bConnection;
bool m_bConnectionEstablished;
bool m_bConnection2Established;
CClasseSocket m_ServerSocket;
CClasseSocket m_Server2Socket;
CClasseSocket m_ClientSocket;
CClasseSocket m_Client2Socket;
void OnClose();
void OnAccept();
CReseauDlg(CWnd* pParent = NULL); // standard constructor

// Dialog Data
//{{AFX_DATA(CReseauDlg)
enum { IDD = IDD_RESEAU_DIALOG };
CButton m_ctrlConnexion;
CListBox m_ctrlTexte;
CString m_strExpedier;
BOOL m_blsServeur;
CString m_strNomServeur;
int m_iPortServeur;
//}}AFX_DATA

// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CReseauDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL

// Implementation
protected:
HICON m_hIcon;

// Generated message map functions
//{{AFX_MSG(CReseauDlg)
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg void OnConnexion();
afx_msg void OnServeur();
afx_msg void OnEnvoyer();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_RESEAUDLG_H__DA3A9147_2BEA_11D4_8BEE_00201854D64E__INCLUDED_)

// ReseauDlg.cpp : implementation file
//

#include "stdafx.h"
#include "Reseau.h"
#include "ReseauDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
CAboutDlg();

// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA

// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
//}}AFX_VIRTUAL

// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP

}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CReseauDlg dialog

CReseauDlg::CReseauDlg(CWnd* pParent /*=NULL*/)
: CDialog(CReseauDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CReseauDlg)
m_strExpedier = _T("");
m_blsServeur = FALSE;
m_strNomServeur = _T("");
m_iPortServeur = 0;
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CReseauDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CReseauDlg)
DDX_Control(pDX, IDC_CONNEXION, m_ctrlConnexion);
DDX_Control(pDX, IDC_TEXTE, m_ctrlTexte);
DDX_Text(pDX, IDC_EXPEDIER, m_strExpedier);
DDX_Check(pDX, IDC_SERVEUR, m_blsServeur);
DDX_Text(pDX, IDC_NOMSERVEUR, m_strNomServeur);
DDX_Text(pDX, IDC_PORTSERVEUR, m_iPortServeur);
//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CReseauDlg, CDialog)
//{{AFX_MSG_MAP(CReseauDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_CONNEXION, OnConnexion)
ON_BN_CLICKED(IDC_SERVEUR, OnServeur)
ON_BN_CLICKED(IDC_ENVOYER, OnEnvoyer)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CReseauDlg message handlers

BOOL CReseauDlg::OnInitDialog()
{
CDialog::OnInitDialog();

// Add "About..." menu item to system menu.

// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);

CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}

// Set the icon for this dialog.  The framework does this automatically
//  when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE);			// Set big icon
SetIcon(m_hIcon, FALSE);		// Set small icon

// TODO: Add extra initialization here
m_blsServeur = false;
m_strNomServeur = _T("localhost");
m_iPortServeur = 1000;
m_ServerSocket.SetParentWindow(this);
m_Server2Socket.SetParentWindow(this);
m_ClientSocket.SetParentWindow(this);
m_Client2Socket.SetParentWindow(this);
m_bConnection = false;
 	m_bConnectionEstablished=false;
m_bConnection2Established=false;
UpdateData(false);

return TRUE;  // return TRUE  unless you set the focus to a control
}

void CReseauDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CReseauDlg::OnPaint() 
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting

SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;

// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CReseauDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}

void CReseauDlg::OnServeur() 
{
// TODO: Add your control notification handler code here

// Lire les données actuelles
UpdateData(true);

// Cette instance fera-t-elle office de serveur ?
if (m_blsServeur)
{
// Oui, changer le texte du bouton
m_ctrlConnexion.SetWindowText("&Attente client");

// Désactiver les champs serveur
GetDlgItem(IDC_NOMSERVEUR)->EnableWindow(false);
GetDlgItem(IDC_PORTSERVEUR)->EnableWindow(false);
}
else
{
// Non, changer le texte du bouton
m_ctrlConnexion.SetWindowText("&Connexion au serveur");

// Activer les champs serveur
GetDlgItem(IDC_NOMSERVEUR)->EnableWindow(true);
GetDlgItem(IDC_PORTSERVEUR)->EnableWindow(true);
}
}

void CReseauDlg::OnConnexion() 
{
// TODO: Add your control notification handler code here
// Acquérir les valeurs actuelles
UpdateData(true);

// Déjà connecté ?
if (!m_bConnection)
{
// Non, désactiver l'élément correspondant
GetDlgItem(IDC_NOMSERVEUR)->EnableWindow(false);
GetDlgItem(IDC_PORTSERVEUR)->EnableWindow(false);
GetDlgItem(IDC_SERVEUR)->EnableWindow(false);

// L'instance est-elle un serveur ?
if (m_blsServeur)
{
// Oui, attendre la connexion
m_ServerSocket.Create(1000);
m_ServerSocket.Listen();

}
else
{
if (m_iPortServeur == 1)
{
// Non, tenter d'établir la connexion par le client 1
m_ClientSocket.Create();
m_ClientSocket.Connect(m_strNomServeur, 
1000);

// Modifier l'inscription de connexion
m_ctrlConnexion.SetWindowText(
"&Déconnexion");
}
else
{
// Non, tenter d'établir la connexion par le client 2
m_Client2Socket.Create();
m_Client2Socket.Connect(m_strNomServeur, 
1000);

// Modifier l'inscription de connexion
m_ctrlConnexion.SetWindowText(
"&Déconnexion");
}
}

// Noter qu'une connexion existe
m_bConnection = true;
}
else
{
// Une connexion existait, en creer une autre
m_Server2Socket.Create(1000);
m_Server2Socket.Listen();
MessageBox("deja connecte !");
}
}

void CReseauDlg::OnAccept()
{
if (!m_bConnectionEstablished)
{
// Accepter la connexion du 1er client
m_ServerSocket.Accept(m_ClientSocket);

// Activer les contrôles correspondants
GetDlgItem(IDC_TEXTE)->EnableWindow(true);
GetDlgItem(IDC_EXPEDIER)->EnableWindow(true);
GetDlgItem(IDC_ENVOYER)->EnableWindow(true);
m_bConnectionEstablished=true;
MessageBox("connection1 !");
}
else
{
// Accepter la connexion de 2eme client
m_Server2Socket.Accept(m_Client2Socket);

// Activer les contrôles correspondants
GetDlgItem(IDC_TEXTE)->EnableWindow(true);
GetDlgItem(IDC_EXPEDIER)->EnableWindow(true);
GetDlgItem(IDC_ENVOYER)->EnableWindow(true);
m_bConnection2Established=true;
MessageBox("connection2 !");
}
}

void CReseauDlg::OnConnect()
{
// Activer les contrôles correspondants
GetDlgItem(IDC_TEXTE)->EnableWindow(true);
GetDlgItem(IDC_EXPEDIER)->EnableWindow(true);
GetDlgItem(IDC_ENVOYER)->EnableWindow(true);
MessageBox("connection2 !");
}

void CReseauDlg::OnEnvoyer() 
{
// TODO: Add your control notification handler code here

// Se procurer les données actuelles
UpdateData(true);

// Lire la chaîne du contrôle
CString strTemp = m_strExpedier;

// Cette instance est-elle le serveur ?
if (m_blsServeur)
{
// Placer le préfixe
strTemp = "Server1: " + strTemp;
if (!m_bConnection2Established)			////////////////////////////////////
{
// Se procurer la longueur de la chaîne
int nSize = strTemp.GetLength();

// Envoyer la chaîne par le 1er client
int nResult = m_ClientSocket.Send(LPCTSTR(strTemp), nSize);

// une erreur s'est-elle produite ?
if (SOCKET_ERROR == nResult)
{
// Oui, afficher message
MessageBox("Erreur lors de l'envoi du texte !");
}
else
{
// Non, ajouter le texte à la ListBox
m_ctrlTexte.AddString(strTemp);
}		///////////////////////////////////////////////////////////////////////
}
else
{
// Se procurer la longueur de la chaîne		////////////////////////////////////////
int nSize = strTemp.GetLength();

// Envoyer la chaîne par le 1er client
int nResult = m_Client2Socket.Send(LPCTSTR(strTemp), nSize);

// une erreur s'est-elle produite ?
if (SOCKET_ERROR == nResult)
{
// Oui, afficher message
MessageBox("Erreur lors de l'envoi du texte !");
}
else
{
// Non, ajouter le texte à la ListBox
m_ctrlTexte.AddString(strTemp);
}		////////////////////////////////////////////////////////////////////////
}
}
else
{
// Placer le préfixe		//************************************************************
strTemp = "Client1: " + strTemp;
if (m_iPortServeur == 1)
{
// Se procurer la longueur de la chaîne
int nSize = strTemp.GetLength();

// Envoyer la chaîne par le 1er client
int nResult = m_ClientSocket.Send(LPCTSTR(strTemp), nSize);

// une erreur s'est-elle produite ?
if (SOCKET_ERROR == nResult)
{
// Oui, afficher message
MessageBox("Erreur lors de l'envoi du texte !");
}
else
{
// Non, ajouter le texte à la ListBox
m_ctrlTexte.AddString(strTemp);
}
}		//***********************************************************************************
else
{
// Se procurer la longueur de la chaîne		//*******************************************
int nSize = strTemp.GetLength();

// Envoyer la chaîne par le 1er client
int nResult = m_Client2Socket.Send(LPCTSTR(strTemp), nSize);

// une erreur s'est-elle produite ?
if (SOCKET_ERROR == nResult)
{
// Oui, afficher message
MessageBox("Erreur lors de l'envoi du texte !");
}
else
{
// Non, ajouter le texte à la ListBox
m_ctrlTexte.AddString(strTemp);
}
}		//************************************************************************************
}

// Actualiser les données des contrôles
UpdateData(false);
}

void CReseauDlg::OnSend()
{
// Méthode intentionnellement vide
}

void CReseauDlg::OnReceive()
{
// Créer les variables locales
char pText[1024];
CString strTemp;

// Recevoir la chaîne
int nResult = m_ClientSocket.Receive(pText, 1024);

// une erreur s'est-elle produite ?
if (SOCKET_ERROR == nResult)
{
// Oui, afficher un message
MessageBox ("Erreur à la réception du texte !");
int nResult = m_Client2Socket.Receive(pText, 1024);
// Ajouter un NULL à la chaîne reçu (désigne
// la fin de la chaîne)
pText[nResult]=NULL;

// Copier le text dans la  variable CString
strTemp = pText;

// Ajouter le texte à la ListBox
m_ctrlTexte.AddString(strTemp);
}
else
{
// Ajouter un NULL à la chaîne reçu (désigne
// la fin de la chaîne)
pText[nResult]=NULL;

// Copier le text dans la  variable CString
strTemp = pText;

// Ajouter le texte à la ListBox
m_ctrlTexte.AddString(strTemp);
}
}

void CReseauDlg::OnClose()
{
// Fermer la conexion
m_ClientSocket.Close();

// Il n'existe plus de connexions (concerne le serveur)
m_bConnectionEstablished=false;

// Activer et désactiver les contrôles de manière appropriée
GetDlgItem(IDC_TEXTE)->EnableWindow(false);
GetDlgItem(IDC_EXPEDIER)->EnableWindow(false);
GetDlgItem(IDC_ENVOYER)->EnableWindow(false);
GetDlgItem(IDC_SERVEUR)->EnableWindow(true);

// Se procurer les données actuelles
UpdateData(true);

// Quelques modifications ne concernant que le client
if (!m_blsServeur)
{
// Activer, désactiver et initaliser les contrôles
GetDlgItem(IDC_NOMSERVEUR)->EnableWindow(true);
GetDlgItem(IDC_PORTSERVEUR)->EnableWindow(true);
m_ctrlConnexion.SetWindowText("&Connexion au serveur");
}
}



voila tout le code source le deuxieme est celui qui gere tout.
mailez moi si vous voulez les autres fichiers
mon adresse e-mail : jrbr@ifrance.com
Messages postés
1905
Date d'inscription
mercredi 22 janvier 2003
Statut
Membre
Dernière intervention
17 septembre 2012
2
Salut,
Il fallais aussi préciser que c'etait en MFC... désolé je ne peux pas t'aider.
Messages postés
546
Date d'inscription
mardi 26 novembre 2002
Statut
Membre
Dernière intervention
4 mai 2007
1
J'ai rien lu de ton code parcque tu n'as pas trop ciblé le probleme mais .. le probleme ne viendré pas des threads?
Messages postés
28
Date d'inscription
samedi 21 juin 2003
Statut
Membre
Dernière intervention
23 mai 2004

en clair mon probleme est que mon programme de chat marche avec 2 clients mais pas avec 3 ou plus.

en fait je n'arrive pas a situer l'erreur et c'est pour sa que je demande de l'aide
Messages postés
1905
Date d'inscription
mercredi 22 janvier 2003
Statut
Membre
Dernière intervention
17 septembre 2012
2
Salut,
Normalement dans un serveur multiclient on stocke tout les sockets dans un tableau.
La j'ai vu aucun tableau, juste:
CClasseSocket m_ClientSocket;
CClasseSocket m_Client2Socket;

A mon avis il va falloir tout retravailler pour accepter plus de deux connections.
Messages postés
28
Date d'inscription
samedi 21 juin 2003
Statut
Membre
Dernière intervention
23 mai 2004

Le probleme n'est pas la je ne cherche pas a faire un programme qui marche du premier coup, pour l'instant j'essaie surtout de comprendre l'utilisation des sockets. La forme n'a que peu d'importance pour le moment. Normalement le code que j'ai ecrit devrait fonctionner correctement meme si je n'ai pas utilise de tableau, la procedure est correcte.
Tout se passe bien jusqu'a l'envoie des donnees et c'est la que je ne comprend plus et c'est pour cette partie justement que j'aimerais quelques conseils parceque je comprend pas la reaction du code. Pour la forme je la reverrais une fois que j'aurais compris le probleme.