• Unreal Engine:Socket源码解析


    一、文件结构

        

      二、SocketTypes.h

    1. Socket类型定义

      2. 连接状态

      3. [ 枚举] socket 接收标志 ESocketReceiveFlags

    • None = 0:返回输入队列中当前可用的尽可能多的数据,达到接收缓冲区的指定大小。
    • Peek = 2: 将接收到的数据复制到缓冲区中,而不将其从输入队列中移除。 
    • WaitAll = 0x100:阻塞接收调用,直到提供的缓冲区已满、连接已关闭、请求已取消或发生错误。 

    4. [ 枚举] socket 等待条件 ESocketWaitConditions

    • WaitForRead
    • WaitForWrite
    • WaitForReadOrWrite

    5. [ 枚举] socket 关闭模式 ESocketShutdownMode

    • Read,Write,ReadWrite

    6. [枚举] 转换时间戳 ETimestampTranslation

    LocalTimestamp:转换为本地时间戳

    TimeDelta:当前平台时间与时间戳的差值

     7. [结构体FRecvMulti

    存储持久状态和数据包缓冲区/数据,用于接收FSocket::RecvMulti数据包。 

    为了优化性能,在套接字的生命周期内只使用该结构的一个实例。

    包括:

    • 当前接收的报文列表:TUniquePtr<FRecvData[]> Packets;       
      • 其中FRecvData结构体包括:
        • 包的源地址:TSharedPtr<FInternetAddr> Source;
        • 指向包数据的指针:const uint8* Data;
        • 指向读取字节数的内部指针:const uint32* BytesReadPtr;
    • 接收的报文数:int32 NumPackets;
    • 支持的最大报文数:const int32 MaxNumPackets;
    • 支持的最大数据包大小:const int32 MaxPacketSize;
    • 检索指定数据包的信息: GetPacket(int32 PacketIdx, FReceivedPacketView& OutPacket)
    • 获取平台指定时间戳:GetPacketTimestamp(int32 PacketIdx, FPacketTimestamp& OutTimestamp)
    • 获取当前接收的数据包数量:GetNumPackets()
    • 获取当前实例的总内存消耗:CountBytes(FArchive& Ar)

    三、Sockets.h

    class FSocket

    protected:

    • const ESocketType SocketType;    //传输协议:None、UDP、TCP
    • FString SocketDescription;     //调试说明
    • FName SocketProtocol;            //创建套接字使用的协议名

    public:

    • 关闭读/写:Shutdown(ESocketShutdownMode Mode)
    • 关闭套接字:Close()
    • 绑定套接字到网络字节序:Bind(const FInternetAddr& Addr)
    • 连接到网络字节序:Connect(const FInternetAddr& Addr)
    • 监听:Listen(int32 MaxBackLog)    //MaxBackLog:拒绝连接之前排队的连接数
    • 等待挂起的连接:WaitForPendingConnection(bool& bHasPendingConnection, const FTimespan& WaitTime)     //bHasPendingConnection:是否被挂起    WaitTime:等待连接的最大时间
    • 确认是否有挂起的连接:HasPendingConnection(bool& bHasPendingConnection)
    • 确认是否有挂起的数据:HasPendingData(uint32& PendingDataSize)
    • 接收一个挂起的连接:FSocket* Accept(const FString& InSocketDescription) /  FSocket* Accept(FInternetAddr& OutAddr, const FString& InSocketDescription) 
    • 发送缓冲区到一个网络字节序:SendTo(const uint8* Data, int32 Count, int32& BytesSent, const FInternetAddr& Destination);
    • 发送缓冲区到一个已连接的套接字:Send(const uint8* Data, int32 Count, int32& BytesSent)
    • 读取数据块并收集源地址:RecvFrom(uint8* Data, int32 BufferSize, int32& BytesRead, FInternetAddr& Source, ESocketReceiveFlags::Type Flags = ESocketReceiveFlags::None)
    • 从已连接的套接字读取数据块:Recv(uint8* Data, int32 BufferSize, int32& BytesRead, ESocketReceiveFlags::Type Flags = ESocketReceiveFlags::None)
    • 阻塞,直到满足特定条件:Wait(ESocketWaitConditions::Type Condition, FTimespan WaitTime)
    • 获取连接状态:GetConnectionState()
    • 读取并返回套接字绑定地址:GetAddress(FInternetAddr& OutAddr)
    • 获取套接字连接端地址:GetPeerAddress(FInternetAddr& OutAddr)
    • 设置为非阻塞模式:SetNonBlocking(bool bIsNonBlocking = true)
    • 设置为广播模式(仅限UDP):SetBroadcast(bool bAllowBroadcast = true)
    • 将此套接字设置为TCP_NODELAY模式(仅TCP):SetNoDelay(bool bIsNoDelay = true)
    • 读取套接字绑定的端口:GetPortNo()
    • 获取套接字绑定的协议类型:GetSocketType()
    • GetDescription()
    • GetProtocol()
    • ...

    四、IPAddress.h

    class FInternetAddr

    public:

    • 比较完成端口:CompareEndpoints(const FInternetAddr& InAddr)
    • 设置IP地址和获取:SetIp()、GetIp()
    • 设置端口号和获取:SetPort()、GetPort()
    • IP地址转为字符串:ToString(bool bAppendPort)    //bAppendPort:是否加入端口信息
    • 比较IP地址 :==
    • 是否合法地址:IsValid()
    • 克隆一个相同结构:TSharedRef<FInternetAddr> Clone()
    • ...

    五、AddressInfoTypes.h

    [枚举] EAddressInfoFlags : uint16

    • AllResults = 1 << 0                 //返回所有地址
    • NoResolveHost = 1 << 1             //不要使用字符串(AI_NUMERICHOST)的DNS解析,这使得地址解析是非阻塞的,要求主机名已经是IP地址的形式
    • NoResolveService = 1 << 2        //不要解析服务名称(要求服务参数为nullptr或基于数字表示的字符串)。 这也是非阻塞的。
    • OnlyUsableAddresses = 1 << 3  //只返回此机器上的适配器可以使用的地址(AI_ADDRCONFIG) 
    • BindableAddress = 1 << 4          //返回可绑定地址(AI_PASSIVE)。 只有当hostname参数为空时才有效
    • CanonicalName = 1 << 5           //在结果列表中包含主机的规范名称
    • FQDomainName = 1 << 6         //在结果列表中包含主机的完全限定域名
    • AllowV4MappedAddresses = 1 << 7    //支持IPv4映射IPv6地址
    • AllResultsWithMapping = AllowV4MappedAddresses | AllResults    //获取所有地址,但返回V4映射的IPv6地址
    • Default = 0                               //平台提示标志的默认值(通常只有0)

    [结构体] FAddressInfoResultData

    [结构体] FAddressInfoResult

    六、SocketSubsystem.h

    ISocketSubsystem

    • 获取单例套接字子系统:ISocketSubsystem* Get(const FName& SubsystemName=NAME_None)
    • 关闭所有已注册的子系统:ShutdownAllSystems()
    • 初始化套接字库:Init(FString& Error)
    • 平台特定套接字清理:Shutdown()
    • 创建套接字:FSocket* CreateSocket(const FName& SocketType, const FString& SocketDescription, bool bForceUDP = false) 
    • 使用给定协议名创建套接字:FSocket* CreateSocket(const FName& SocketType, const FString& SocketDescription, const FName& ProtocolName)
    • 创建一个unique_ptr指向的套接字,将自动调用DestroySocket:CreateUniqueSocket(const FName& SocketType, const FString& SocketDescription, bool bForceUDP = false) /  CreateUniqueSocket(const FName& SocketType, const FString& SocketDescription, const FName& ProtocolName)
    • 清理套接字:DestroySocket(FSocket* Socket)
    • 保存解析后地址:FResolveInfoCached* CreateResolveInfoCached(TSharedPtr<FInternetAddr> Addr) 
    • 获取给定主机名地址信息:GetAddressInfo
    • GetAddressInfo的异步变体:GetAddressInfoAsync
  • 相关阅读:
    atitit.nfc 身份证 银行卡 芯片卡 解决方案 attilax总结
    atitit.php 流行框架 前三甲为:Laravel、Phalcon、Symfony2 attilax 总结
    Atitit.执行cmd 命令行 php
    Atitit. 图像处理jpg图片的压缩 清理垃圾图片 java版本
    atitit。企业组织与软件工程的策略 战略 趋势 原则 attilax 大总结
    atitit. 管理哲学 大毁灭 如何防止企业的自我毁灭
    Atitit.java的浏览器插件技术 Applet japplet attilax总结
    Atitit.jquery 版本新特性attilax总结
    Atitit. 软件开发中的管理哲学一个伟大的事业必然是过程导向为主 过程导向 vs 结果导向
    (转)获取手机的IMEI号
  • 原文地址:https://www.cnblogs.com/tomatokely/p/16442505.html
Copyright © 2020-2023  润新知