wie schon in meinem letzten Post ( GCC und Templates ) geht es um meine Netzwerkbibliothek aber diesmal rein um das Design. Die Idee hinter meinem Framework ist das Protokoll bzw die Implementation des Protokolls komplett hinter einem Interface zu verstecken, dass für alle Implementierungen gleich ist.
Also etwa so:
Dabei habe ich jetzt zwei Protokolle/Implementierungen einmal für TCP und einmal für UDP. Beide benutzen die normalen C-Sockets und kein Boost::ASIO oder so. INetworkPort sieht zur Zeit so aus:
Code: Alles auswählen
class INetworkPort
{
public:
INetworkPort(INetworkCallback* callback_, u16 maxPeers_, u16 portNumber_, bool listening_, bool IPv6_) : callback(callback_), maxPeers(maxPeers_), portNumber(portNumber_), listening(listening_), IPv6(IPv6_)
{
callback->onCreate(this);
}
virtual ~INetworkPort(void)
{
callback->onDestroy();
}
//! Gets the callback
INetworkCallback* getCallback(void)
{
return callback;
}
//! Gets the used (listening) port number
u16 getPortNumber(void) const
{
return portNumber;
}
//! Get the maximum numbers of possible peers
u16 getMaxPeers(void) const
{
return maxPeers;
}
//! States if the port is an IPv6 port
bool isIPv6(void) const
{
return IPv6;
}
//! Is the port listening for new connections?
bool isListening(void) const
{
return listening;
}
//! Initialization function
virtual bool init() = 0;
//! Connect to an address
//! Returns false if already connected
virtual bool connect(const SNetworkAddress& address) = 0;
//! The disconnect pendant
//! Returns false if the peerID is invalid
virtual bool disconnect(const PeerID id) = 0;
//! Disconnects all peers
//! Returns number of peers disconnected
virtual u16 disconnectAll(void) = 0;
//! Gets the address (IP/Port) of a peer
virtual SNetworkAddress getAddress(const PeerID id) = 0;
//! Get the latency of a peer
virtual s32 getLatency(const PeerID id)= 0;
//! Looks up if a certain address is connected
virtual bool isConnected(const SNetworkAddress& a) = 0;
//! Gets the Id of a certain address
virtual PeerID getPeer(const SNetworkAddress& a) = 0;
//! Sends and receives data
virtual void work(void) = 0;
//! Get the protocol used
virtual EPortType getType() const = 0;
//! Send data to peer - Reliable or not
virtual bool send(const PeerID id, const u8 type, const u32 length, const c8* data, const bool reliable) = 0;
//! Send data to peer (BitStream Version) - Reliable or not
virtual bool send(const PeerID id, const u8 type, const BitStream& bstream, const bool reliable) = 0;
//! Send data to address (Raw)
virtual bool sendRaw(const SNetworkAddress& address, const u16 length, const c8* data) = 0;
//! Query certain features
virtual bool hasFeature(EFeatureType type) const = 0;
//! Returns number of peers connected
virtual u16 getPeerCount() = 0;
protected:
//! The callback used for all events etc
INetworkCallback* callback;
//! The amount of connections possible
u16 maxPeers;
//! The port used
u16 portNumber;
//! Listen Flag
bool listening;
//! Is uning IPv6?
bool IPv6;
};
Für die zuverlässigen Pakete mache ich jetzt einfach Folgendes. Ich gebe jedem Paket eine ID (16-bit unsigned integer) und schicke dann ein Paket vom Empfänger mit der ID zurück um zu zeigen dass es angekommen ist. Nach 2*Latenz wird das Paket erneut verschickt wenn keine Antwort kam. Um doppeltes Empfangen zu verhindern speicher ich auf der Empfängerseite die zuletzt empfangenen IDs. Reihenfolge ist mir egal, soll auch egal sein (sonst könnte ich gleich TCP verwenden).
Mein Fragen hier:
1. Ist das vom Ansatz her intelligent?
2. Verhinder damit ja nicht dass der Inhalt des Pakets kaputt ist oder ähnliches. (Teste zurzeit nur ob die Länge korrekt ist, irgendwelche Checksums scheinen mir zu viel Overhead.
Dann bei den großen Paketen mach ich Folgendes. Ich teile ein Paket in Chunks afu die ich dann mit der oberen Methode sende und auf der Empfängerseite wieder zusammen setz.
Mein Fragen hier:
1. Das scheint für mich ein großer Overhead, kann man das irgendwie intelligenter Lösen?
2. Sollte ich ab einer bestimmten größe komprimieren (mit zlib o.ä.)?
schonmal ein Danke an euch,
Halan