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