einfaches multiplayer?



  • hiho
    ich hab da mial ne große frage ^^

    kann mir jemand einen einfachen quelltext schreiben wo man eine variable vom
    server zu client und von client zu host übertragen kann ...

    weil ich hab bis jetz noch kein mir leicht verständliches beispiel
    gefunden ...

    bitte helft mir !! derzeit übertrage ich die multiplayerdaten nur per textdatei
    aber das nervt, weil ich auch irgendwann mal ein internetfähiges programm bauen
    möchte

    thx & mfg M0rPh3u5 😋



  • ach ja das programm ist in MFC geschrieben und ich hab WinXP

    mfg M0rPh3u5



  • http://www.c-worker.ch -> Tutorials

    MfG Mailmaster



  • Es gibt da in MFC eine echt nette Klasse: CAsyncSocket
    Mach dazu Mysocket.h

    #pragma once
    
    // CMySocket-Befehlsziel
    
    class CMySocket : public CAsyncSocket
    {
    public:
    	CMySocket();
    	virtual ~CMySocket();
    	void SetParent(CDialog* pWnd);
    	CDialog* m_pWnd;
    protected:
    	virtual void OnAccept(int nErrorCode);
    	virtual void OnConnect(int nErrorCode);
    	virtual void OnClose(int nErrorCode);
    	virtual void OnReceive(int nErrorCode);
    	virtual void OnSend(int nErrorCode);
    };
    

    und Mysocket.cpp

    // MySocket.cpp : Implementierungsdatei
    //
    
    #include "stdafx.h"
    #include "Sender.h"
    #include "SenderDlg.h"
    #include ".\mysocket.h"
    
    // CMySocket
    
    CMySocket::CMySocket()
    {
    }
    
    CMySocket::~CMySocket()
    {
    }
    
    // CMySocket-Memberfunktionen
    
    void CMySocket::SetParent(CDialog* pWnd)
    {
    	m_pWnd = pWnd;
    }
    void CMySocket::OnAccept(int nErrorCode)
    {
    	if(nErrorCode==0)
    	{
    		((CSenderDlg*)m_pWnd)->OnAccept();
    	}
    	CAsyncSocket::OnAccept(nErrorCode);
    }
    void CMySocket::OnConnect(int nErrorCode)
    {
    	if(nErrorCode==0)
    	{
    		((CSenderDlg*)m_pWnd)->OnConnect();
    	}
    	CAsyncSocket::OnConnect(nErrorCode);
    }
    
    void CMySocket::OnClose(int nErrorCode)
    {
    	if(nErrorCode==0)
    	{
    		((CSenderDlg*)m_pWnd)->OnClose();
    	}
    	CAsyncSocket::OnClose(nErrorCode);
    }
    
    void CMySocket::OnReceive(int nErrorCode)
    {
    	if(nErrorCode==0)
    	{
    		((CSenderDlg*)m_pWnd)->OnReceive();
    	}
    	CAsyncSocket::OnReceive(nErrorCode);
    }
    
    void CMySocket::OnSend(int nErrorCode)
    {
    	if(nErrorCode==0)
    	{
    		((CSenderDlg*)m_pWnd)->OnSend();
    	}
    	CAsyncSocket::OnSend(nErrorCode);
    }
    

    wobei du CSenderDlg durch deinen eigenen Dialog ersetzt und diesen oben
    auch im include änderst. (Beim Empfänger Dialog halt CEmpfängerDlg oder s.ä.)
    Die Dateien müssen ins Projekt aufgenommen werden.

    Dann kommt im Init Bereich beim Sender:

    m_connectsocket.SetParent(this);
    	if (m_connectsocket.Create()){};
    

    einen Connect Button mit folgendem Inhalt:

    CString serverip = "127.0.0.1";  //oder richtige IP über ein IP Feld
    	if(m_connectsocket.Connect(serverip,4444)){}
    	else{}
    

    einen SendeButtn mit folgender Funktion:

    int bu[7];
    	bu[0]=1;
    	bu[1]=2;
    	bu[2]=3;
    	bu[3]=5;
    	bu[4]=4;
    	bu[5]=6;
    	bu[6]=7;
       int *buffer = bu;
       m_connectsocket.Send(buffer,(7*4))==SOCKET_ERROR){MessageBox("Sendefehler");
    

    Geht natürlich auch mit einem CString, und bei Send(buffer,x) kommt immer die
    Länge rein, was bei z.B. einem Int 4Byte*7 wäre und beim CString einfach 7 wäre.

    folgende Funktionen noch rein:
    in der MeinDlg.h unter puplic

    void OnAccept(void);
    	void OnConnect(void);
    	void OnClose(void);
    	void OnReceive(void);
    	void OnSend(void);
    	CMySocket m_connectsocket;
    

    und in der MeinDlg.cpp

    void CForceSenderDlg::OnAccept(void)
    {
    }
    
    void CForceSenderDlg::OnConnect(void)
    {
       //hier Code, wenn ein Connect im Senderdialog wirklich stattfindet
    }
    
    void CForceSenderDlg::OnClose(void)
    {
    }
    
    void CForceSenderDlg::OnReceive(void)
    {
    }
    
    void CForceSenderDlg::OnSend(void)
    {
    }
    

    Erzeuge den neuen MFC Dialog mit Winsock Zusatz (Häckchen) oder mach manuell
    in die stdafx.h

    #include <afxsock.h>		// MFC-Socket-Erweiterungen
    

    Vergiss die Includes in allen Dialogen nicht.

    Dann im Empfangsdialog:
    in der EmpfangDlg.h :

    void OnAccept(void);
    	void OnConnect(void);
    	void OnClose(void);
    	void OnReceive(void);
    	void OnSend(void);
    	CMySocket m_listensocket;
    	CMySocket m_connectsocket;
    

    Wichtig, hier braucht man zwei CMySocket.
    und dann dieselben Funktionen OnAccept etc. wie im Senderdialog.
    Unter dem Init beim Empfang kommt dann:

    m_listensocket.SetParent(this);
    	m_connectsocket.SetParent(this);
    	if (m_listensocket.Create(4444)){}
    	else{MessageBox("Nix mit Socket");OnOK();}
    	if (m_listensocket.Listen()){}
    	else{MessageBox("Nix mit Listen");OnOK();}
    

    Die Accept Funktion wird so erweitert:

    void CEmpfangDlg::OnAccept(void)
    {
    	m_listensocket.Accept(m_connectsocket);
    	//hier deinen Code, der irgendwas macht, wenn eine Verbindung da ist
    }
    

    Und die OnReceive:

    void CEmpfangDlg::OnReceive(void)
    {
    
      int *pBuf = new int[1025];
      int iBufSize = 1024;
      if (m_connectsocket.Receive(pBuf, iBufSize) == SOCKET_ERROR)
      {
    	  MessageBox("Receive Error");
      }
      else
      {
             //hier kannst du dann die pBuf in ein Array übergeben
             // z.B. buffer[0]=pBuf[0]; //etc. vorher buffer deklarieren :)
      }
    

    Die Größe des Buffers kann / sollte größer sein.
    Bei starker Auslast des Systemes gibt es übrigens Fehlübertragungen, welche
    hier erkannt werden müssen.

    Im Ganzen geht es wie folgt ab, nach drücken des Connect buttons auf der
    Senderseite wird die Accept Funktion im Empfängerdialog aufgerufen, dann
    wird dort bestätigt und nun kann beliebig gesendet und empfangen werden.
    Und das immer mit den jeweiligen OnSend / OnReceive als Messages.
    Einfacher gehts nicht. Die DirectPlay Variante mit Chat etc. ist mir da
    zu umständlich.
    Mehr zu diesem Thema im Buch "In 21 Tagen C++.Net Kapitel 18" oder
    "In 21 Tagen c++ v6" Kapitel 21.

    Nun aber loslos ...
    }



  • Kein Wort zu WSAEWOULDBLOCK?



  • Nö, soll erstmal soweit kommen.



  • vielleicht kannst du mir auch beim meinem Propblem helfen. habe alles so wie oben und so wie im Buch und so wie auf zfx beschrieben geschrieben. NUr leider habe ich ein Problem.

    http://www.c-plusplus.net/forum/viewtopic-var-t-is-129585.html

    Hier habe ich mein Problem mal etwas genauer bschrieben.


Anmelden zum Antworten