Files CCore/inc/net/PacketEndpointDevice.h CCore/src/net/PacketEndpointDevice.cpp
Files CCore/inc/net/XPoint.h CCore/src/net/XPoint.cpp
Packet endpoints are a base of the CCore networking. There are two abstract packet endpoint interface: PacketEndpointDevice and PacketMultipointDevice. All network code is enclosed in the Net namespace.
PacketEndpointDevice is a "client-side" interface. It is a logical packet communication endpoint. It is used in point-to-point communication scenarios.
struct PacketEndpointDevice
{
static const Unid TypeUnid;
virtual PacketFormat getOutboundFormat() const =0;
virtual void outbound(Packet<uint8> packet)=0;
virtual ulen getMaxInboundLen() const =0;
struct InboundProc : InterfaceHost
{
static const Unid TypeUnid;
virtual void inbound(Packet<uint8> packet,PtrLen<const uint8> data)=0;
virtual void tick()=0;
};
struct ConnectionProc // optional for InboundProc
{
static const Unid TypeUnid;
virtual void connection_lost()=0;
virtual void connection_close()=0;
};
virtual void attach(InboundProc *proc)=0;
virtual void detach()=0;
};
getOutboundFormat() returns the outbound packet format.
outbound() starts the packet outbound. When the packet processing is complete, the packet is completed. There is no error signaling, because the communication is not assumed reliable. The fact the packet is processed does not mean the data are received or will be received by the communication peer.
getMaxInboundLen() is a maximum inbound data length.
Data income is an asynchronous process. So to receive incoming packets some inbound processor must be attached to the endpoint.
attach() attaches the given processor to the endpoint. Only one processor can be attached at any time. Processor must be detached before endpoint is destroyed. Processor methods are called in an unknown task context.
detach() detaches inbound processor from the endpoint.
inbound() is called to handle an inbound packet. The first argument is a packet, the second is an inbound data, it is a part of the packet data buffer.
tick() is a "network tick". It happens 10 times per second. It is used for a protocol timeout processing.
InboundProc interface may have the optional co-interface ConnectionProc to handle disconnection events.
connection_lost() is called in the case of a connection lost situation.
connection_close() is called if the peer has requested to close the connection.
PacketMultipointDevice is a "server-side" interface. It is a logical packet communication endpoint. It is used in point-to-many points communication scenarios. The type XPoint is used to identify a particular target.
using XPoint = uint64 ;
PacketMultipointDevice is similar to the PacketEndpointDevice. The difference is the address argument in inbound() and outbound() methods. This argument is the address the packet should be sent to or is received from. ConnectionProc methods also have the address argument. It also has one additional method: connection_open() is called to signal about connection opening with a peer.
struct PacketMultipointDevice { static const Unid TypeUnid; virtual StrLen toText(XPoint point,PtrLen<char> buf) const =0; virtual PacketFormat getOutboundFormat() const =0; virtual void outbound(XPoint point,Packet<uint8> packet)=0; virtual ulen getMaxInboundLen() const =0; struct InboundProc : InterfaceHost { static const Unid TypeUnid; virtual void inbound(XPoint point,Packet<uint8> packet,PtrLen<const uint8> data)=0; virtual void tick()=0; }; struct ConnectionProc // optional for InboundProc { static const Unid TypeUnid; virtual void connection_open(XPoint point)=0; virtual void connection_lost(XPoint point)=0; virtual void connection_close(XPoint point)=0; }; virtual void attach(InboundProc *proc)=0; virtual void detach()=0; };
toText() creates a text representation of the target address. A buffer for the operation must be given. The resulting text is returned.
Multipoint device can store a native address in the type XPoint, if it is short enough. It also can perform an address mapping from the native address to the type XPoint.
This optional co-interface for PacketEndpointDevice and PacketMultipointDevice interfaces implements the "port" abstraction. Some address schemes (like UDP) uses the concept of port. Port is a part of the address.
struct PortManager
{
static const Unid TypeUnid;
virtual XPoint getDevicePort() const =0;
virtual XPoint getPort(XPoint point) const =0;
virtual XPoint changePort(XPoint point,XPoint port) const =0;
};
getDevicePort() returns the port of the device object in the form of the XPoint value.
getPort() extracts the port from the given address. Both port and address are represented by the XPoint value.
changePort() changes the port of the given address and returns the resulting address.
const unsigned InboundTicksPerSec = 10 ;
This constant is the net tick frequency.
inline constexpr unsigned ToTickCount(MSec timeout)
{
return ((+timeout)*InboundTicksPerSec)/1000+1;
}
This function converts the time, given as MSec, to the net tick count.
class PointDesc : NoCopy
{
char buf[TextBufLen];
StrLen str;
public:
PointDesc(const PacketMultipointDevice *mp,XPoint point)
{
str=mp->toText(point,Range(buf));
}
StrLen getStr() const { return str; }
// print object
using PrintOptType = StrPrintOpt ;
template <class P>
void print(P &out,PrintOptType opt) const
{
Putobj(out,BindOpt(opt,str));
}
};
This class helps to convert an XPoint to the text string.