Bei Google wird auch direkt an die Speicherstelle Packet->data geschrieben. Habe mein Problem mit dem Speicherzugriffsfehler gefunden. Ich hatte noch eine Broadcastfunktion (frame(), nun auskommentiert) laufen, welche den Packet->data Zeiger immer auf 0 gesetzt hat. Jetzt kann ich zwar auch Daten in das Paket schreiben, aber empfangen kann ich sie trotzdem nicht. Ich schreib jetzt mal allen netzwerkrelevanten Code zusammen. Vielleicht sieht ja jemand einen Fehler, den ich übersehen habe:
Die gekürzte main.cpp, Client u. Server, haben den gleichen Quelltext, werden durch SERVER-Makro unterschieden:
Code: Alles auswählen
//#define SERVER
	//Netzwerkobjekt erstellen
	GLNet Netzwerk(&Zeit);
	char Daten[1024] = {0};
	int Laenge = 6;
	int SourceNumber = 0;
	bool Server = true;
	#ifdef SERVER
	//Als Empfängerserver verbinden
	Netzwerk.setName("Empfängerserver");
	Netzwerk.UDPServer();
	#else
	//Als Senderclient verbinden
	Netzwerk.setName("Senderclient");
	Netzwerk.UDPClient();
	Netzwerk.ClientToIP(127, 0, 0, 1);	//localhost
	#endif
	while(!Input.getQuit())
	{
		//Netzwerkframefunktion
		//Netzwerk.frame();
		#ifdef SERVER
		if(Netzwerk.RecvUDP(Daten, Laenge, SourceNumber, Server) && SourceNumber != -1)
		{
			//Daten konvertieren
			std::string Stringtext;
			if(Daten[0] == 5)
				Stringtext = "Juhu!";
			else
				Stringtext = "Mist!";
			std::string Ausgabe = "Empfangen: ";
			Ausgabe += Stringtext;
			Output.writel(Ausgabe, 0, 1);
		}
		#else
		//Daten senden
        	if(Input.isRepeated("enter") && Netzwerk.getState() != "Nicht verbunden/Not connected")
        	{
			char* Text = const_cast<char*> (Eingabe->getText().c_str());
			Netzwerk.SendUDP((void*)Text, Eingabe->getText().length());
			//Sendebericht ausgeben
			std::string Sendingmessage = (std::string)Text;
			Sendingmessage += " gesendet an ";
			//Anderer Benutzer muss erste Person in Datenbank sein
			if(Netzwerk.getState() == "UDPServer")
			{
		        	Sendingmessage += Netzwerk.getClientIP(0);
			} else {
				Sendingmessage += Netzwerk.getServerIP(0);
			}
			Output.writel(Sendingmessage, 0, 1);
			Eingabe->setText("");
		}
		#endif
	}
Die Sende- Empfangsfunktion:
Code: Alles auswählen
void GLNet::SendUDP(void* daten, int laenge)
{
	//Wenn keine UDP-Verbindung, abbrechen
	if(State == 0 || State == 1 || State == 2) return;
	Packet->data[0] = 5;
	Packet->len = 1;
	//Wenn UDP-Server, an alle Clients senden, sonst an alle Server
	if(State == 3 || State == 5 || State == 7)
	{
		for(int i = 0; i < NumberClients; i++)
		{
			//IP zuweisen
			Packet->address.host = ClientIP[i].host;
			Packet->address.port = ClientIP[i].port;
			//An eine Adresse (Client) senden
			SDLNet_UDP_Send(UDPSocket, -1, Packet);
		}
	} else {
		for(int i = 0; i < NumberServer; i++)
		{
			//IP zuweisen
			Packet->address.host = ServerIP[i].host;
			Packet->address.port = ServerIP[i].port;
			//An eine Adresse (Server) senden
			SDLNet_UDP_Send(UDPSocket, -1, Packet);
		}
	}
}
bool GLNet::RecvUDP(void* daten, int& maxlaenge, int& number, bool& server)			//Liefert true zurück, wenn neue Daten vorhanden (z.B. für Abfrageschleife)
{
	//Wenn keine UDP-Verbindung, abbrechen
	if(State == 0 || State == 1 || State == 2) return false;
	if(SDLNet_UDP_Recv(UDPSocket, Packet) != 1) return false;
	daten = (void*)Packet->data;
	maxlaenge = Packet->len;
	return true;
}
Ich erhalte keinerlei Fehlermeldungen, kann also Daten in das Paket schreiben. Aber die Serverversion meines Programms gibt mir wenn ich ein Paket absende immer "Empfangen: Mist!" aus, also keine "5" auf dem ersten Byte des Pakets.
Die Funktionen zum Verbindungsaufbau, stehen hier nur vorsichtshalber, eine Verbindung erhalte ich ja:
Code: Alles auswählen
void setName(std::string name) {if(State != 0 && State != 3 && State != 4) SendTCPNameChange(name); else Name = name;} //irrelevant, da der Name noch nicht verwendet wird
bool GLNet::UDPServer()
{
	//Falls UDPClient, Verbindung beenden
	if(State == 4 || State == 6 || State == 8)
		EndUDP();
	//Nur neu verbinden, wenn noch nicht UDPServer
	if(State != 3 && State != 5 && State != 7)
	{
		UDPSocket = SDLNet_UDP_Open(Port);
		//Wenn Socket auf diesem Port nicht erstellen geht, Status anpassen und abbrechen
		if(UDPSocket == NULL)
		{
			//Status passend ändern, da keine UDP-Verbindung mehr und Serververbindung fehlgeschlagen
			switch(State)
			{
				case 4:
					//UDPClient -> nicht verbunden
					State = 0;
				break;
				case 6:
					//TCPServer/UDPClient -> TCPServer
					State = 1;
				break;
				case 8:
					//TCPClient/UDPClient -> TCPClient
					State = 2;
				break;
			}
			return false;
		}
		//Speicher für Paket reservieren
		Packet = SDLNet_AllocPacket(Plaenge);
		//Status aktualisieren
		switch(State)
		{
			case 0:
				//nicht verbunden -> UDPServer
				State = 3;
			break;
			case 1:
				//TCPServer -> TCPServer/UDPServer
				State = 5;
			break;
			case 2:
				//TCPClient -> TCPClient/UDPServer
				State = 7;
			break;
			case 4:
				//UDPClient -> UDPServer
				State = 3;
			break;
			case 6:
				//TCPServer/UDPClient -> TCPServer/UDPServer
				State = 5;
			break;
			case 8:
				//TCPClient/UDPClient -> TCPClient/UDPServer
				State = 7;
			break;
		}
	}
	return true;
}
bool GLNet::UDPClient()
{
	//Falls UDPServer, Verbindung beenden
	if(State == 3 || State == 5 || State == 7)
		EndUDP();
	//Nur neu verbinden, wenn noch nicht UDPClient
	if(State != 4 && State != 6 && State != 8)
	{
		UDPSocket = SDLNet_UDP_Open(0);		//Nächsten freien Port auswählen, sicherer, dass funktioniert (Server erhält Clientports in Paketen)
		//Wenn Socket nicht erstellen geht, Status anpassen und abbrechen
		if(UDPSocket == NULL)
		{
			//Status passend ändern, da keine UDP-Verbindung mehr und Clientverbindung fehlgeschlagen
			switch(State)
			{
				case 3:
					//UDPServer -> nicht verbunden
					State = 0;
				break;
				case 5:
					//TCPServer/UDPServer -> TCPServer
					State = 1;
				break;
				case 7:
					//TCPClient/UDPServer -> TCPClient
					State = 2;
				break;
			}
			return false;
		}
		//Speicher für Paket reservieren
		Packet = SDLNet_AllocPacket(Plaenge);
		//Status aktualisieren
		switch(State)
		{
			case 0:
				//nicht verbunden -> UDPClient
				State = 4;
			break;
			case 1:
				//TCPServer -> TCPServer/UDPClient
				State = 6;
			break;
			case 2:
				//TCPClient -> TCPClient/UDPClient
				State = 8;
			break;
			case 3:
				//UDPServer -> UDPClient
				State = 4;
			break;
			case 5:
				//TCPServer/UDPServer -> TCPServer/UDPClient
				State = 6;
			break;
			case 7:
				//TCPClient/UDPServer -> TCPClient/UDPClient
				State = 8;
			break;
		}
	}
	return true;
}
bool GLNet::ClientToIP(unsigned char IP1, unsigned char IP2, unsigned char IP3, unsigned char IP4)
{
	return add(IP1, IP2, IP3, IP4, true);
}
bool GLNet::add(unsigned char IP1, unsigned char IP2, unsigned char IP3, unsigned char IP4, bool server, std::string userName, int ping, double lastAnswer)
{
	//IP konvertieren
	Uint32 IP = (IP1 << 24) + (IP2 << 16) + (IP3 << 8) + IP4 ;
	unsigned char Puffer[4] = {0};
	SDLNet_Write32(IP, Puffer);
	IPaddress Adresse;
	Adresse.host = (Puffer[3] << 24) + (Puffer[2] << 16) + (Puffer[1] << 8) + Puffer[0];
	unsigned char SmallPuffer[2] = {0};
	SDLNet_Write16(Port, SmallPuffer);
	Adresse.port = (SmallPuffer[1] << 8) + SmallPuffer[0];
	//SDLNet_ResolveHost(&Adresse, "localhost", Port);	//Nur für Testzwecke
	//Schauen ob Server oder Client hinzugefügt wird
	if(server)
	{
		if(NumberServer <= 255)
		{
			//In Adressdatenbank eintragen
			ServerIP[NumberServer] = Adresse;
			ServerName[NumberServer] = userName;    //Entweder ein Name gesetzt oder ist leer
			ServerPing[NumberServer] = ping;    //Entweder ein Ping gesetzt oder ist 0
			if(lastAnswer != -1) LastServerAnswer[NumberServer] = lastAnswer; else LastServerAnswer[NumberServer] = Time->getGametime();
			NumberServer++;
			return true;
		} else {
			return false;
		}
	} else {
		if(NumberClients <= 255)
		{
			//In Adressdatenbank eintragen
			ClientIP[NumberClients] = Adresse;
			ClientName[NumberClients] = userName;    //Entweder ein Name gesetzt oder ist leer
			ClientPing[NumberClients] = ping;    //Entweder ein Ping gesetzt oder ist 0
			if(lastAnswer != -1) LastClientAnswer[NumberClients] = lastAnswer; else LastClientAnswer[NumberClients] = Time->getGametime();
			NumberClients++;
			return true;
		} else {
			return false;
		}
	}
}
void GLNet::EndUDP()
{
	if(UDPSocket) SDLNet_UDP_Close(UDPSocket);
	UDPSocket = NULL;
	if(Packet) SDLNet_FreePacket(Packet);
	Packet = NULL;
	//Status aktualisieren
	switch(State)
	{
		case 3:
			//UDPServer -> nicht verbunden
			State = 0;
		break;
		case 4:
			//UDPClient -> nicht verbunden
			State = 0;
		break;
		case 5:
			//TCPServer/UDPServer -> TCPServer
			State = 1;
		break;
		case 6:
			//TCPServer/UDPClient -> TCPServer
			State = 1;
		break;
		case 7:
			//TCPClient/UDPServer -> TCPClient
			State = 2;
		break;
		case 8:
			//TCPClient/UDPClient -> TCPClient
			State = 2;
		break;
	}
}