MFC - Daten schicken mit CAsyncSocket



  • Hallo zusammen,

    Ich lerne gerade mit MFC zu programmieren.
    Im Moment bin ich an einem "Schiffe versenken" Spiel dran, dass über TCP/IP von zwei Personen gespielt werden kann. Ich nutze dafür CAsyncSocket.

    Nun kann ich jedoch keine Daten senden. Wenn ich Daten über den Telnet Client schicke, funktioniert alles tadellos, vom Programm selber aus gesendet komme ich nicht mal ist OnReceive().

    Spieler 1 hört auf Port 55162 und sendet auf 55163 und Spieler 2 umgekehrt.

    Hier ein Bisschen Code.

    Bei OnInitDlg werden die jeweiligen Server Sockets erstellt:

    ...
    m_Listener.Create(55162);			// Auf Port 55162 hören
    
    if(m_Listener.Listen() == FALSE)	// Wenn Port schon von einem anderen Spieler besetzt
    	{ 
    		m_Listener.Close();
    
    		iPlayer = 2;					// Dann ist dieser Spieler 2
    		m_Listener.Create(55163);		// Es wird auf Port 55163 gehört
    
    		if(m_Listener.Listen() == FALSE)	// Falls beide Ports bereits besetzt
    		{
    			MessageBox(TEXT("Weder Port 55162, noch Port 55163 ist verfügbar."), NULL, MB_ICONHAND);
    			m_Listener.Close();
    			m_Connected.Close();
    			exit(0);				// Ende der Aplikation
    		}
    ...
    

    Nach der Eingabe der IP des anderen Spielers und Drücken des "Verbinden" Buttons:

    ...
    GetDlgItemText(IDC_IPADDRESS, strIPAddress);
    	tempIpAddress = strIPAddress;
    
    	if(iPlayer == 1)
    	{
    		m_Connected.Create(55163);
    		m_Connected.Connect(strIPAddress, 55163);
    	}
    	else if(iPlayer == 2)
    	{
    		m_Connected.Create(55162);
    		m_Connected.Connect(strIPAddress, 55162);
    	}
    
    	m_StartServerButton.EnableWindow(false);
    	m_PlaceButton.EnableWindow(true);
    	GotoDlgCtrl(GetDlgItem(IDC_EDIT_PLACE));
    	m_Instructions.SetWindowTextW(TEXT("Setzen Sie Ihre Schiffe."));
    ...
    

    Nach dem Setzen aller Schiffe:

    ...
    if(m_ShipCount == 30)
    	{
    		m_PlaceButton.EnableWindow(false);
    
    		if(iPlayer == 1)
    		{
    			m_Instructions.SetWindowTextW(TEXT("Warten Sie bis Ihr Gegner seine Schiffe gesetzt hat."));
    		}
    		else if(iPlayer == 2)
    		{
    			m_Instructions.SetWindowTextW(TEXT("Warten Sie auf den gegnerischen Zug."));
    			MessageTempForBuffer = "R";
    
    			m_Connected.Send(MessageTempForBuffer.GetBuffer(), MessageTempForBuffer.GetLength());
    		}
    	}
    ...
    

    Dabei wir nur berücksichtigt, ob der zweite Spieler bereits fertig ist mit dem Setzen der Schiffe (Implemetation für Spieler 1 folgt noch).

    Das gesendete "R" soll aussagen "Ready". Die Nachrichten (Befehle) werden sich noch ändern.
    Nun komme ich aber nicht ins OnReceive() des ersten Spielers. Sprich, die Nachricht kommt gar nicht erst an.

    Kann mir jemand helfen 😕

    Danke im Voraus !



  • Nun habe ich meinen ein anderes Problem.

    GetDlgItemText(IDC_IPADDRESS, strIPAddress);	// IP-Adresse in Variable strIPAddress kopieren.
    	tempIpAddress = strIPAddress;
    
    	if(iPlayer == 1)	// Spieler 1 verbindet sich auf Port 55163
    	{
    		m_Connected.Create(55164);
    		m_Connected.Connect(strIPAddress, 55163);
    	}
    	else if(iPlayer == 2)	// Spieler 2 verbindet sich auf Port 55162
    	{
    		m_Connected.Create(55165);
    		m_Connected.Connect(strIPAddress, 55162);
    	}
    

    Bei Socket.Create() des zweiten zu verbindenden Spielers tritt ein "Debug Assertion Failed" auf.

    BOOL CAsyncSocket::Socket(int nSocketType, long lEvent,
    	int nProtocolType, int nAddressFormat)
    {
    	ASSERT(m_hSocket == INVALID_SOCKET);     // Hier tritt der Fehler angeblich auf.
    
    	m_hSocket = socket(nAddressFormat,nSocketType,nProtocolType);
    	if (m_hSocket != INVALID_SOCKET)
    	{
    		CAsyncSocket::AttachHandle(m_hSocket, this, FALSE);
    		return AsyncSelect(lEvent);
    	}
    	return FALSE;
    }
    

    Weiss jemand was das zu bedeuten hat?

    _



  • NewUser123 schrieb:

    Weiss jemand was das zu bedeuten hat?_

    Vermutlich rufst du auf demselben Socket-Objekt zweimal Create auf.

    Deine Verwendung der Sockets sieht aber auch sonst ziemlich merkwürdig aus. Warum benutzt du CAsyncSocket? Und rufst du auch irgendwo Accept auf?



  • Ich bin noch Anfänger im Thema Sockets und zu CAsyncSocket habe ich ein gutes Beispiel gefunden.

    Hier rufe ich Accept auf:

    void CBattleshipsDlg::OnAccept()
    {
    	UINT port;
    	CString TempIPADRESS;
    
    	if(m_Listener.Accept(m_Connected))
    	{
    		m_Connected.GetSockName(TempIPADRESS, port);
    	}
    	else
    	{
    		MessageBox(TEXT("Verbindung kann nicht angenommen werden."), NULL, MB_ICONHAND);
    		m_Connected.Close();
    	}
    }
    


  • °
    Hallo, das Problem konnte behoben werden.
    Ich baute eine TCP/IP Verbindung auf (die ja bidirektional läuft) und versuchte die zwei Spieler gleich nochmals zu verbinden.
    °


Anmelden zum Antworten