Files
UnrealEngine/Engine/Source/Runtime/Sockets/Public/Sockets.h
2025-05-18 13:04:45 +08:00

477 lines
16 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "Containers/UnrealString.h"
#include "CoreMinimal.h"
#include "CoreTypes.h"
#include "Misc/Timespan.h"
#include "SocketTypes.h"
#include "UObject/NameTypes.h"
#include "UObject/UnrealNames.h"
class FInternetAddr;
/**
* This is our abstract base class that hides the platform specific socket implementation
*/
class FSocket : public TSharedFromThis<FSocket, ESPMode::ThreadSafe>
{
protected:
/** Indicates the type of socket this is */
const ESocketType SocketType;
/** Debug description of socket usage. */
FString SocketDescription;
/** Protocol used in creation of a socket */
FName SocketProtocol;
public:
/** Default constructor. */
SOCKETS_API FSocket();
/**
* Specifies the type of socket being created
*
* @param InSocketType The type of socket being created
* @param InSocketDescription The debug description of the socket
*/
UE_DEPRECATED(4.22, "Please migrate to the constructor that specifies protocol stack")
inline FSocket(ESocketType InSocketType, const FString& InSocketDescription) :
SocketType(InSocketType),
SocketDescription(InSocketDescription),
SocketProtocol(NAME_None)
{ }
UE_DEPRECATED(4.23, "Please migrate to the constructor that takes an FName for the protocol stack")
inline FSocket(ESocketType InSocketType, const FString& InSocketDescription, ESocketProtocolFamily InSocketProtocol) :
SocketType(InSocketType),
SocketDescription(InSocketDescription)
{
if (InSocketProtocol == ESocketProtocolFamily::IPv4)
{
SocketProtocol = FNetworkProtocolTypes::IPv4;
}
else if (InSocketProtocol == ESocketProtocolFamily::IPv6)
{
SocketProtocol = FNetworkProtocolTypes::IPv6;
}
else
{
SocketProtocol = NAME_None;
}
}
/**
* Specifies the type of socket being created
*
* @param InSocketType The type of socket being created
* @param InSocketDescription The debug description of the socket
* @param InSocketProtocol the protocol stack this socket should be created on.
*/
SOCKETS_API FSocket(ESocketType InSocketType, const FString& InSocketDescription, const FName& InSocketProtocol);
/** Virtual destructor. */
SOCKETS_API virtual ~FSocket();
/**
* Shuts down the socket, making it unusable for reads and/or writes. This does not close the socket!
*
* @param Types
* @return true if successful, false otherwise.
*/
virtual bool Shutdown(ESocketShutdownMode Mode) = 0;
/**
* Closes the socket
*
* @return true if it closes without errors, false otherwise.
*/
virtual bool Close() = 0;
/**
* Binds a socket to a network byte ordered address.
*
* @param Addr The address to bind to.
* @return true if successful, false otherwise.
*/
virtual bool Bind(const FInternetAddr& Addr) = 0;
/**
* Connects a socket to a network byte ordered address.
*
* @param Addr The address to connect to.
* @return true if successful, false otherwise.
*/
virtual bool Connect(const FInternetAddr& Addr) = 0;
/**
* Places the socket into a state to listen for incoming connections.
*
* @param MaxBacklog The number of connections to queue before refusing them.
* @return true if successful, false otherwise.
*/
virtual bool Listen(int32 MaxBacklog) = 0;
/**
* Waits for a pending connection on the socket.
*
* @param out bHasPendingConnection Will indicate whether a connection is pending or not.
* @param WaitTime The maximum time to wait for a connection. If zero, the function will not
* wait and will return immediately with a value in bHasPendingConnection.
* @return true if successful, false otherwise.
*/
virtual bool WaitForPendingConnection(bool& bHasPendingConnection, const FTimespan& WaitTime) = 0;
/**
* Queries the socket to determine if there is a pending connection.
*
* @param bHasPendingConnection Will indicate whether a connection is pending or not.
* @return true if successful, false otherwise.
*/
bool HasPendingConnection(bool& bHasPendingConnection)
{
return WaitForPendingConnection(bHasPendingConnection, FTimespan::Zero());
}
/**
* Queries the socket to determine if there is pending data on the queue.
*
* @param PendingDataSize Will indicate how much data is on the pipe for a single recv call.
* @return true if the socket has data, false otherwise.
*/
virtual bool HasPendingData(uint32& PendingDataSize) = 0;
/**
* Accepts a connection that is pending.
*
* @param SocketDescription Debug description of socket,
* @return The new (heap-allocated) socket, or nullptr if unsuccessful.
*/
virtual class FSocket* Accept(const FString& InSocketDescription) = 0;
/**
* Accepts a connection that is pending.
*
* @param OutAddr The address of the connection.
* @param SocketDescription Debug description of socket.
* @return The new (heap-allocated) socket, or nullptr if unsuccessful.
*/
virtual class FSocket* Accept(FInternetAddr& OutAddr, const FString& InSocketDescription) = 0;
/**
* Sends a buffer to a network byte ordered address.
*
* @param Data The buffer to send.
* @param Count The size of the data to send.
* @param BytesSent Will indicate how much was sent.
* @param Destination The network byte ordered address to send to.
*/
SOCKETS_API virtual bool SendTo(const uint8* Data, int32 Count, int32& BytesSent, const FInternetAddr& Destination);
/**
* Sends a buffer on a connected socket.
*
* @param Data The buffer to send.
* @param Count The size of the data to send.
* @param BytesSent Will indicate how much was sent.
*/
SOCKETS_API virtual bool Send(const uint8* Data, int32 Count, int32& BytesSent);
/**
* Reads a chunk of data from the socket and gathers the source address.
*
* A return value of 'true' does not necessarily mean that data was returned.
* Callers must check the 'BytesRead' parameter for the actual amount of data
* returned. A value of zero indicates that there was no data available for reading.
*
* @param Data The buffer to read into.
* @param BufferSize The max size of the buffer.
* @param BytesRead Will indicate how many bytes were read from the socket.
* @param Source Will contain the receiving the address of the sender of the data.
* @param Flags The receive flags.
* @return true on success, false in case of a closed socket or an unrecoverable error.
*/
SOCKETS_API virtual bool RecvFrom(uint8* Data, int32 BufferSize, int32& BytesRead, FInternetAddr& Source, ESocketReceiveFlags::Type Flags = ESocketReceiveFlags::None);
/**
* Reads a chunk of data from a connected socket
*
* A return value of 'true' does not necessarily mean that data was returned.
* Callers must check the 'BytesRead' parameter for the actual amount of data
* returned. A value of zero indicates that there was no data available for reading.
*
* @param Data The buffer to read into
* @param BufferSize The max size of the buffer
* @param BytesRead Will indicate how many bytes were read from the socket
* @param Flags the receive flags
* @return true on success, false in case of a closed socket or an unrecoverable error.
*/
SOCKETS_API virtual bool Recv(uint8* Data, int32 BufferSize, int32& BytesRead, ESocketReceiveFlags::Type Flags = ESocketReceiveFlags::None);
/**
* Reads multiple packets from the socket at once, gathering the source address and other optional platform specific data.
* Use ISocketSubsystem::IsSocketRecvMultiSupported to check if the current socket platform supports this.
* NOTE: For optimal performance, one FRecvMulti instance should be used, for the lifetime of the socket.
*
* @param MultiData The FRecvMulti instance that receives packet data and holds platform specific buffers for receiving data.
* @param Flags The receive flags.
* @return Whether or not data was successfully received
*/
SOCKETS_API virtual bool RecvMulti(FRecvMulti& MultiData, ESocketReceiveFlags::Type Flags=ESocketReceiveFlags::None);
/**
* Blocks until the specified condition is met.
*
* @param Condition The condition to wait for.
* @param WaitTime The maximum time to wait.
* @return true if the condition was met, false if the time limit expired or an error occurred.
*/
virtual bool Wait(ESocketWaitConditions::Type Condition, FTimespan WaitTime) = 0;
/**
* Determines the connection state of the socket.
*
* @return Connection state.
*/
virtual ESocketConnectionState GetConnectionState() = 0;
/**
* Reads the address the socket is bound to and returns it.
*
* @param OutAddr The address the socket is bound to.
*/
virtual void GetAddress(FInternetAddr& OutAddr) = 0;
/**
* Reads the address of the peer the socket is connected to.
*
* @param OutAddr Address of the peer the socket is connected to.
* @return true if the address was retrieved correctly, false otherwise.
*/
virtual bool GetPeerAddress(FInternetAddr& OutAddr) = 0;
/**
* Sets this socket into non-blocking mode.
*
* @param bIsNonBlocking Whether to enable blocking or not.
* @return true if successful, false otherwise.
*/
virtual bool SetNonBlocking(bool bIsNonBlocking = true) = 0;
/**
* Sets a socket into broadcast mode (UDP only).
*
* @param bAllowBroadcast Whether to enable broadcast or not.
* @return true if successful, false otherwise.
*/
virtual bool SetBroadcast(bool bAllowBroadcast = true) = 0;
/**
* Sets this socket into TCP_NODELAY mode (TCP only).
*
* @param bIsNoDelay Whether to enable no delay mode.
* @return true if successful, false otherwise.
*/
virtual bool SetNoDelay(bool bIsNoDelay = true) = 0;
/**
* Joins this socket to the specified multicast group.
*
* The multicast group address must be in the range 224.0.0.0 to 239.255.255.255.
*
* @param GroupAddress The IP address of the multicast group.
* @return true on success, false otherwise.
* @see LeaveMulticastGroup, SetMulticastLoopback, SetMulticastTtl
*/
virtual bool JoinMulticastGroup(const FInternetAddr& GroupAddress) = 0;
/**
* Joins this socket to the specified multicast group on the specified interface.
*
* The multicast group address must be in the range 224.0.0.0 to 239.255.255.255.
*
* @param GroupAddress The IP address of the multicast group.
* @param InterfaceAddress The address representing the interface.
* @return true on success, false otherwise.
* @see LeaveMulticastGroup, SetMulticastLoopback, SetMulticastTtl
*/
virtual bool JoinMulticastGroup(const FInternetAddr& GroupAddress, const FInternetAddr& InterfaceAddress) = 0;
/**
* Removes this UDP client from the specified multicast group.
*
* @param The multicast group address to leave.
* @return true on success, false otherwise.
* @see JoinMulticastGroup, SetMulticastLoopback, SetMulticastTtl
*/
virtual bool LeaveMulticastGroup(const FInternetAddr& GroupAddress) = 0;
/**
* Removes this UDP client from the specified multicast group on the specified interface.
*
* @param GroupAddress The multicast group address to leave.
* @param InterfaceAddress The address representing the interface.
* @return true on success, false otherwise.
* @see JoinMulticastGroup, SetMulticastLoopback, SetMulticastTtl
*/
virtual bool LeaveMulticastGroup(const FInternetAddr& GroupAddress, const FInternetAddr& InterfaceAddress) = 0;
/**
* Enables or disables multicast loopback on the socket (UDP only).
*
* This setting determines whether multicast datagrams are looped
* back to the sending socket. By default, multicast loopback is
* enabled. It must be enabled if more than one listener is present
* on a host.
*
* @param bLoopback Whether loopback should be enabled.
* @see LeaveMulticastGroup, JoinMulticastGroup, SetMulticastTtl
*/
virtual bool SetMulticastLoopback(bool bLoopback) = 0;
/**
* Sets the time to live (TTL) for multicast datagrams.
*
* The default TTL for multicast datagrams is 1, which prevents them
* from being forwarded beyond the local subnet. Higher values will
* allow multicast datagrams to be sent into neighboring subnets, if
* multicast capable routers are present.
*
* @param TimeToLive Number of hops the datagram can make.
* @see LeaveMulticastGroup, JoinMulticastGroup, SetMulticastLoopback
*/
virtual bool SetMulticastTtl(uint8 TimeToLive) = 0;
/**
* Sets the interface used to send outgoing multicast datagrams.
*
* Multicast traffic is sent using the default interface, this allows
* to explicitly set the interface used to send outgoing multicast datagrams.
*
* @param InterfaceAddress The interface address.
* @return true if the call succeeded, false otherwise.
*/
virtual bool SetMulticastInterface(const FInternetAddr& InterfaceAddress) = 0;
/**
* Sets whether a socket can be bound to an address in use.
*
* @param bAllowReuse Whether to allow reuse or not.
* @return true if the call succeeded, false otherwise.
*/
virtual bool SetReuseAddr(bool bAllowReuse = true) = 0;
/**
* Sets whether and how long a socket will linger after closing.
*
* @param bShouldLinger Whether to have the socket remain open for a time period after closing or not.
* @param Timeout The amount of time to linger before closing.
* @return true if the call succeeded, false otherwise.
*/
virtual bool SetLinger(bool bShouldLinger = true, int32 Timeout = 0) = 0;
/**
* Enables error queue support for the socket.
*
* @param bUseErrorQueue Whether to enable error queuing or not.
* @return true if the call succeeded, false otherwise.
*/
virtual bool SetRecvErr(bool bUseErrorQueue = true) = 0;
/**
* Sets the size of the send buffer to use.
*
* @param Size The size to change it to.
* @param NewSize Will contain the size that was set (in case OS can't set that).
* @return true if the call succeeded, false otherwise.
*/
virtual bool SetSendBufferSize(int32 Size, int32& NewSize) = 0;
/**
* Sets the size of the receive buffer to use.
*
* @param Size The size to change it to.
* @param NewSize Will contain the size that was set (in case OS can't set that).
* @return true if the call succeeded, false otherwise.
*/
virtual bool SetReceiveBufferSize(int32 Size, int32& NewSize) = 0;
/**
* Sets whether to retrieve the system-level receive timestamp, for sockets
*
* @param bRetrieveTimestamp Whether to retrieve the timestamp upon receive
* @return True if the call succeeded, false otherwise.
*/
SOCKETS_API virtual bool SetRetrieveTimestamp(bool bRetrieveTimestamp=true);
/**
* Reads the port this socket is bound to.
*
* @return Port number.
* @see GetSocketType, GetDescription
*/
virtual int32 GetPortNo() = 0;
/**
* Sets whether to enable IP_PKTINFO support
*
* @param bEnable Whether to enable/disable
* @return True if the call succeeded, false otherwise.
*/
SOCKETS_API virtual bool SetIpPktInfo(bool bEnable);
/**
* Reads a chunk of data from the socket and gathers the source address and the destination using IP_PKTINFO
*
* A return value of 'true' does not necessarily mean that data was returned.
* Callers must check the 'BytesRead' parameter for the actual amount of data
* returned. A value of zero indicates that there was no data available for reading.
*
* @param Data The buffer to read into.
* @param BufferSize The max size of the buffer.
* @param BytesRead Will indicate how many bytes were read from the socket.
* @param Source Will contain the receiving the address of the sender of the data.
* @param Destination Will contain the destination address used by the sender of the data.
* @param Flags The receive flags.
* @return true on success, false in case of a closed socket or an unrecoverable error.
*/
SOCKETS_API virtual bool RecvFromWithPktInfo(uint8* Data, int32 BufferSize, int32& BytesRead, FInternetAddr& Source, FInternetAddr& Destination, ESocketReceiveFlags::Type Flags = ESocketReceiveFlags::None);
/**
* Get the type of protocol the socket is bound to
*
* @return Socket type.
* @see GetDescription, GetPortNo
*/
FORCEINLINE ESocketType GetSocketType() const
{
return SocketType;
}
/**
* Get the debug description of the socket.
*
* @return Debug string.
* @see GetPortNo, GetSocketType
*/
FORCEINLINE FString GetDescription() const
{
return SocketDescription;
}
/**
* Get the type of protocol the socket is bound to
*
* @return Socket type.
* @see GetDescription, GetPortNo
*/
FORCEINLINE FName GetProtocol() const
{
return SocketProtocol;
}
};