1 Server zu 4 Clients für Mensch ärgere Dich nicht



  • Guten Morgen allesamt,
    also ich Programmiere gerade ein Mensch ärgere Dich nicht, dass auf Netzwerk gespielt werden soll. Nun, das Spiel steht schon zum Spielen bereit (wer Quellcode will, soll sich melden). Auch eine geeignete Server Client Anwendung hab ich schon gefunden (es können sich unzählig viele Clients gleichzeitig an einen Server mit tcp anmelden). Auch sendet der Server seine Messages an alle angeschlossenen Clients.
    Mein Problem ist aber: Ich will die einzelnen Clients nacheinander zum Senden auffordern. Dazu muß ich meinem Datenstring noch die Information des nächsten sendeberechtigten Teilnehmers anfügen. Leider ist der bisher verschickte String vom Typ CEdit und nicht vom Typ CString. Untenstehend hab ich noch den Quellcode angefügt. Um evtl. Lösungsvorschläge bezüglich Array in String umwandeln und zurück + anfügen der Sendeberechtigung des nächsten Teilnehmers wär ich sehr dankbar.
    P.S. Wer Server Client Verbindung mit UDP Protokoll braucht, ist bei mir an der richtigen Stelle.

    Hier die Server CPP in Ausschnitten:

    // ServerSocketDlg.cpp : implementation file
    
    /////////////////////////////////////////////////////////////////////////////
    // CServerSocketDlg message handlers
    
    BOOL CServerSocketDlg::PreTranslateMessage(MSG* pMsg) 
    {
    	if (pMsg->message == WM_KEYDOWN)
    	{
    		int nVirtKey = (int) pMsg->wParam;
    		if (nVirtKey == VK_ESCAPE)
    			return TRUE;
    		if (nVirtKey == VK_RETURN && (GetFocus()->m_hWnd  == m_ctlMessage.m_hWnd))
    		{
    			if (m_pCurServer->IsOpen())
    				OnBtnSend();
    			return TRUE;
    		}
    	}
    
    	return CDialog::PreTranslateMessage(pMsg);
    }
    
    ///////////////////////////////////////////////////////////////////////////////
    // PickNextAvailable : this is useful only for TCP socket
    void CServerSocketDlg::PickNextAvailable()
    {
    	m_pCurServer = NULL;
    	for(int i=0; i<MAX_CONNECTION; i++)
    	{
    		if (!m_SocketManager[i].IsOpen())
    		{
    			m_pCurServer = &m_SocketManager[i];
    			break;
    		}
    	}
    }
    
    BOOL CServerSocketDlg::OnInitDialog()
    {
    	// TODO: Add extra initialization here
    	m_ctlPortInc.SetRange32( 2000, 4500);
    	GetDlgItem(IDC_BTN_SEND)->EnableWindow( FALSE );
    	GetDlgItem(IDC_BTN_STOP)->EnableWindow( FALSE );
    
    	for(int i=0; i<MAX_CONNECTION; i++)
    	{
    		m_SocketManager[i].SetMessageWindow( &m_ctlMsgList );
    		m_SocketManager[i].SetServerState( true );	// run as server
    	}
    
    	PickNextAvailable();
    
    	return TRUE;  // return TRUE  unless you set the focus to a control
    }
    
    void CServerSocketDlg::OnSysCommand(UINT nID, LPARAM lParam)
    {
    	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
    	{
    		CAboutDlg dlgAbout;
    		dlgAbout.DoModal();
    	}
    	else
    	{
    		CDialog::OnSysCommand(nID, lParam);
    	}
    }
    
    ///////////////////////////////////////////////////////////////////////////////
    // OnUpdateConnection
    // This message is sent by server manager to indicate connection status
    LRESULT CServerSocketDlg::OnUpdateConnection(WPARAM wParam, LPARAM lParam)
    {
    	UINT uEvent = (UINT) wParam;
    	CSocketManager* pManager = reinterpret_cast<CSocketManager*>( lParam );
    
    	// We need to do this only for TCP socket
    	if (m_nSockType != SOCK_TCP)
    		return 0L;
    
    	if ( pManager != NULL)
    	{
    		// Server socket is now connected, we need to pick a new one
    		if (uEvent == EVT_CONSUCCESS)
    		{
    			PickNextAvailable();
    			StartServer();
    		}
    		else if (uEvent == EVT_CONFAILURE || uEvent == EVT_CONDROP)
    		{
    			pManager->StopComm();
    			if (m_pCurServer == NULL)
    			{
    				PickNextAvailable();
    				StartServer();
    			}
    		}
    	}
    	return 1L;
    }
    
    ////////////////////////////////////////////////////////////////////////////////////////////////
    //************************************SERVER WIRD GESTARTET********************
    void CServerSocketDlg::OnBtnStart() 
    {
    	UpdateData();
        Anzahl_Spieler = 0;
        m_einmal_gesendet = false;
    	StartServer();
    }
    
    ////////////////////////////////////////////////////////////////////////////////////////////////
    //**************************** StartServer : Start the server******************
    bool CServerSocketDlg::StartServer()
    {
    	bool bSuccess = false;
    	if (m_pCurServer != NULL)
    	{
    		if (m_nSockType == SOCK_TCP)
    		{
    			// no smart addressing - we use connection oriented
    			m_pCurServer->SetSmartAddressing( false );
    			bSuccess = m_pCurServer->CreateSocket( m_strPort, AF_INET, SOCK_STREAM, 0); // TCP
    		}
    
    		if (bSuccess && m_pCurServer->WatchComm())
    		{
    			GetDlgItem(IDC_BTN_SEND)->EnableWindow( TRUE );
    			GetDlgItem(IDC_BTN_STOP)->EnableWindow( TRUE );
    			NextDlgCtrl();
    			GetDlgItem(IDC_BTN_START)->EnableWindow( FALSE );
    			GetDlgItem(IDC_TCP)->EnableWindow( FALSE );
    			GetDlgItem(IDC_UDP)->EnableWindow( FALSE );
    			CString strServer, strAddr;
    			m_pCurServer->GetLocalName( strServer.GetBuffer(256), 256);
    			strServer.ReleaseBuffer();
    			m_pCurServer->GetLocalAddress( strAddr.GetBuffer(256), 256);
    			strAddr.ReleaseBuffer();
    			CString strMsg = _T("Server: ") + strServer;
    					strMsg += _T(", @Address: ") + strAddr;
    					strMsg += _T(" is running on port ") + m_strPort + CString("\r\n");
    			m_pCurServer->AppendMessage( strMsg );
    		    Anzahl_Spieler++;
            }
    	}
    	return bSuccess;
    }
    
    /////////////////////////////////////////////////////////////////////////////////////////////////
    //******************************ALLE CLIENTS WERDEN GESCHLOSSEN****************
    void CServerSocketDlg::OnBtnStop() 
    {
    	// Disconnect all clients
    	for(int i=0; i<MAX_CONNECTION; i++)
    		m_SocketManager[i].StopComm();
    
    	if (!m_pCurServer->IsOpen())
    	{
    		GetDlgItem(IDC_BTN_START)->EnableWindow( TRUE );
    		PrevDlgCtrl();
    		GetDlgItem(IDC_BTN_STOP)->EnableWindow( FALSE );
    		GetDlgItem(IDC_TCP)->EnableWindow( TRUE );
    		GetDlgItem(IDC_UDP)->EnableWindow( TRUE );
    	}
    }
    
    ////////////////////////////////////////////////////////////////////////////////////////////
    //*************************ALLE CLIENTS ERHALTEN MESSAGE DES SERVER************
    void CServerSocketDlg::OnBtnSend() 
    {
    	CString strText;
        int nLen;
        stMessageProxy msgProxy;
    
    //Abfrage ob Spiel beginnen kann, wurde von mir hinzugefügt
    
        if (Anzahl_Spieler == MAX_CONNECTION && m_einmal_gesendet == false)
            {
            m_Spielstartet.GetWindowText( strText );
        	nLen = strText.GetLength();
            }
    
        if (Anzahl_Spieler == MAX_CONNECTION && m_einmal_gesendet == true)
            {
            m_ctlMessage.GetWindowText( strText );
        	nLen = strText.GetLength();
            }
    
    	if (nLen > 0)
    	{
    		USES_CONVERSION;
    		strText += _T("\r\n");
            //Länge des Strings wird ermittelt
    		nLen = strText.GetLength();  
            //String wird zum Versenden vorbereitet
    		nLen = __min(sizeof(msgProxy.byData)-1, nLen+1);
    		memcpy(msgProxy.byData, T2CA(strText), nLen);
    
    		// Send data to peer...
    		// Send to all clients
    		for(int i=0; i<MAX_CONNECTION; i++)
    		{
    			if (m_SocketManager[i].IsOpen() && m_pCurServer != &m_SocketManager[i])
    				m_SocketManager[i].WriteComm(msgProxy.byData, nLen, INFINITE);
    		}
        m_einmal_gesendet = true;
    	}
    }	
    
    ///////////////////////////////////////////////////////////////////////////////////////////////
    //*********************AllE VERBINDUNGEN ZU CLIENTS WERDEN GETRENNT************
    void CServerSocketDlg::OnDestroy() 
    {
    	for(int i=0; i<MAX_CONNECTION; i++)
    	m_SocketManager[i].StopComm();
    
    	CDialog::OnDestroy();	
    }
    
    // The system calls this to obtain the cursor to display while the user drags
    //  the minimized window.
    HCURSOR CServerSocketDlg::OnQueryDragIcon()
    {
    	return (HCURSOR) m_hIcon;
    }
    

    Hier die CPP der Clients:

    /////////////////////////////////////////////////////////////////////////////
    // CClientSocketDlg message handlers
    
    BOOL CClientSocketDlg::PreTranslateMessage(MSG* pMsg) 
    {
    	if (pMsg->message == WM_KEYDOWN)
    	{
    		int nVirtKey = (int) pMsg->wParam;
    		if (nVirtKey == VK_ESCAPE)
    			return TRUE;
    
    		if (nVirtKey == VK_RETURN && (GetFocus()->m_hWnd  == m_ctlMessage.m_hWnd))
    		{
    			if (m_SocketManager.IsOpen())
    				OnBtnSend();
    			return TRUE;
    		}
    	}
    
    	return CDialog::PreTranslateMessage(pMsg);
    }
    
    BOOL CClientSocketDlg::OnInitDialog() 
    {
    //*****************************************************************************
    	// TODO: Add extra initialization here
    	m_ctlPortInc.SetRange32( 2000, 4500);               //Festlegen der min. und max. Portnummer
    	GetDlgItem(IDC_BTN_SEND)->EnableWindow( FALSE );
    	GetDlgItem(IDC_BTN_STOP)->EnableWindow( FALSE );
    
    	CString strLocal;
    	m_SocketManager.GetLocalAddress( strLocal.GetBuffer(256), 256);
    	strLocal.ReleaseBuffer();
    	m_ctlIPAddress.SetWindowText( strLocal );
    
    	// Initialize socket manager
    	m_SocketManager.SetMessageWindow( &m_ctlMsgList );                  //gibt Adresse der Client/Server im Dialogfeld aus
    	m_SocketManager.SetServerState( false );	// run as client
    	m_SocketManager.SetSmartAddressing( false );	// always send to server
    //*****************************************************************************
    	return TRUE;  // return TRUE unless you set the focus to a control
    	              // EXCEPTION: OCX Property Pages should return FALSE
    }
    
    ///////////////////////////////////////////////////////////////////////////////
    //*****************************************VERBINDUNG HERSTELLEN***************
    void CClientSocketDlg::OnBtnConnect() 
    {
    	UpdateData();
    
    	CString strServer;
    	m_ctlIPAddress.GetWindowText( strServer );
    	bool bSuccess;
    
        //TCP VERBINDUNGSAUFBAU
    	bSuccess = m_SocketManager.ConnectTo( strServer, m_strPort, AF_INET, SOCK_STREAM); 
    
    	if (bSuccess && m_SocketManager.WatchComm())
    	{
    		GetDlgItem(IDC_BTN_SEND)->EnableWindow( TRUE );
    		GetDlgItem(IDC_BTN_STOP)->EnableWindow( TRUE );
    		NextDlgCtrl();
    		GetDlgItem(IDC_BTN_START)->EnableWindow( FALSE );
    		GetDlgItem(IDC_TCP)->EnableWindow( FALSE );
    		GetDlgItem(IDC_UDP)->EnableWindow( FALSE );
    		CString strMsg;
    
    		strMsg = _T("Connection established with server: ") + strServer;
    		strMsg += _T(" on port ") + m_strPort + CString("\r\n");
    		m_SocketManager.GetPeerName( m_SockPeer );
    
    		m_ctlMsgList.SetWindowText( strMsg );
    	}
    }
    
    ///////////////////////////////////////////////////////////////////////////////
    //*******************************MESSAGE WIRD AN SERVER GESENDET*************
    void CClientSocketDlg::OnBtnSend() 
    {
    	BYTE byBuffer[256] = { 0 };
    	CString strText;
    
    	// Update so that we can retrieve new port number also... :-)
    	UpdateData();
    	m_ctlMessage.GetWindowText( strText );
        int nLen = strText.GetLength();
    
    	if (nLen > 0)
    	{
    		strText += _T("\r\n");
    		nLen = strText.GetLength() + 1;
    		USES_CONVERSION;
    		strcpy((LPSTR)byBuffer, T2CA(strText));
    		m_SocketManager.WriteComm( byBuffer, nLen, INFINITE);
    	}
    }
    
    ///////////////////////////////////////////////////////////////////////////////
    //***********************************VERBINDUNG WIRD GETRENNT*****************
    void CClientSocketDlg::OnBtnDisconnect() 
    {
    	// Disconnect socket
    	m_SocketManager.StopComm();
    	if (!m_SocketManager.IsOpen())
    	{
    		GetDlgItem(IDC_BTN_START)->EnableWindow( TRUE );
    		PrevDlgCtrl();
    		GetDlgItem(IDC_BTN_SEND)->EnableWindow( FALSE );
    		GetDlgItem(IDC_BTN_STOP)->EnableWindow( FALSE );
    		GetDlgItem(IDC_TCP)->EnableWindow( TRUE );
    		GetDlgItem(IDC_UDP)->EnableWindow( TRUE );
    	}
    }
    
    ///////////////////////////////////////////////////////////////////////////////
    //***********************************VERBINDUNG WIRD GETRENNT*****************
    void CClientSocketDlg::OnDestroy() 
    {
    	m_SocketManager.StopComm();
    	CDialog::OnDestroy();
    }
    


  • Moin,
    zu Quellcode, ja hätte ich gern.

    Ich habe ein Netzwerkspiel so prog das auf dem Server eine Statusdatei angelegt ist, dort steht dann z.B. drin welches Spieler am Zug ist.

    Die anderen warten dann auf Änderungen an der statusdatei.



  • Aloha,

    die Server Client quellcode, den du gefunden hast würde mich interessieren.
    Schick doch mal bitte.

    Grüße

    BOA


Anmelden zum Antworten