ue4集合类型_UE4-Sockets
Sockets(套接字)
套接字為通信的端點。通過網絡通信的每對進程需要使用一對套接字。
套接字組成: IP地址 + 端口號
套接字采用客戶機——服務器架構。
服務器通過監聽指定端口,來等待客戶請求。
實現特定服務的服務器監聽眾所周知的端口:
- telent服務器端口,23
- ftp服務器監聽端口,21
- web或http服務器,80
所有低于1024的端口都是眾所周知的。
客戶端
發出請求Socket: 客戶端IP + 大于1024且唯一的端口號。 例如: 146.86.5.20:1625 所有連接都必須是唯一的,當另一個進程與同一個服務器建立連接時,應該被分配大于1024且不等于1625的端口。
IP 127.0.0.1為特殊IP,回送(loopback),它引用自己,這一機制允許同一主機的客戶機和服務器可以通過TCP/IP協議進行通信。
BSD Sockts API
伯克利套接字(Berkeley sockets)定義了一組用于進程間Sockets通信的通用API,sockets的實現依賴于不同的操作系統各有所不同,在實現了BSD Sockets接口的操作系統上,就可以很方便地移植采用BSD Sockets API的應用程序。所有現代操作系統都實現了BSD Sockets。
常用API:
- socket() 創建Socket,分配一些系統資源。
- bind() 通常用于服務端,將一個socket和一個socket地址結構關聯,它指定了本地IP地址和端口號,可設定為綁定到本機的任何IP。
- listen() 用在服務端,使得一個被綁定的TCP socket進入監聽狀態。
- connect() 用在客戶端,分配給Socket一個空閑的端口號,對于TCP Socket,還會嘗試建立一個新的TCP連接。
- accept() 用在服務端,它接受來自遠程客戶端的創建TCP連接的請求(connect),并創建一個新的Socket來表示這次連接兩端的Sockets。
- send(), recv(), sendto(), and recvfrom() 用于發送和接收數據,標準IO函數write()和read()也可以使用。
- close() 使系統釋放一個socket的資源,在TCP下,連接會終止。
- gethostbyname() and gethostbyaddr() 用于獲取host名字和地址。僅在IPv4下可用。
- select() 用于掛起,等待列表中的一個或多個套接字準備好讀取或寫入或出現錯誤。
- poll() 檢查在socket集合中的一個socket的狀態。這個集合可以被測試是否有socket可以被寫入或讀出或出現錯誤。
- getsockopt() 獲取一個socket的的指定socket 選項的當前值。
- setsockopt() 設置一個socket的指定socket選項的值。
UE4 Sockets
UE4針對眾多不同的操作系統的不同的Socket實現提供了同一的Socket編程接口。由于幾乎所有操作系統都實現了BSD socket接口,利用這一點可以方便地統一一些基本的Socket接口。同時,不同的操作系統也提供了一些差異化的操作,這些操作由ISocketSubsystem定義。
class FSocket
這個類定義了類似于BSD socket API 的抽象接口。包括:
Close(),Bind(),Listen(), Connect(),Accept(),Send(),Recv(),等操作。此外,還有一些便利操作:
WaitForPendingConnection(),HasPendingConnection(),可判斷是否有連接請求。 HasPendingData(),查詢是否有即將到來的數據可以接收。 RecvMulti(),一次讀取多個數據包,還有許多其它操作...
class FSocketBSD
FSocketBSD繼承自FSocket,它實現了所有FSocket的接口,跨平臺的操作就是在這里實現的。
首先會通過PLATFORM_HAS_BSD_SOCKETS判斷當前平臺是否支持BSD socket接口,以決定是否定義FSocketBSD類。
在BSDSockets/SocketSubsystemBSDPrivate.h文件中,根據不同的平臺包含不同平臺的BSD socket API實現頭文件。并統一原始Socket對象的類型為SOCKET,這一類型在WinSock中有定義:
typedef UINT_PTR SOCKET;但在其它平臺則沒有,比如在Unix系統下就直接用的int類型表示socket對象指針。所以在其它情況下還會加上一些類型別名:
typedef int32 SOCKET;// ... ...它的幾個成員變量:
/** Holds the BSD socket object. */SOCKET Socket;/** Last activity time. */double LastActivityTime;/** Pointer to the subsystem that created it. */ISocketSubsystem* SocketSubsystem;其中SocketSubsystem表示的是創建這個FSocketBSD的子系統,其中定義的是平臺特異的操作。
class ISocketSubsystem
這是抽象平臺特異的sockets API的基本接口。其功能有:
- Get(const FName&) 獲取指定平臺的ISocketSubsystem單例。
- 不同平臺的初始化操作
- 創建和銷毀Sockets。
- Host name 到IP address 的域名解析。包括異步的域名解析。
- 創建恰當的FInternetAddr表示。
- CreateRecvMulti()
- TMap<FString, TSharedPtr<FInternetAddr> > HostNameCache; host Name的緩存
class FSocketSubsystemBSD
此外,它還派生出FSocketSubsystemBSD對應于FSocketBSD。它實現了標準的BSD支持的一些socket 子系統的操作。
也是在這里,實現了CreateSocket(), 其中也是調用了平臺特異的BSD socket API socket()實現的。先通過平臺特異的原始socket()構造函數創建SOCKET,這一步其實將所有支持BSD socket API 的操作系統都考慮了進去,再進一步創建FSocketBSD,最后根據ISocketSubsystem定義的接口,返回FSocket.
Observe
UE 定義的這一Socket模塊,大體上分兩個主要的繼承線路,一個是FSocket是表示通信的一端的socket,定義了BSD 中的常規操作,以及一些額外的便利操作(RecvMulti())。另一條是ISocketSubsystem,這是抽象平臺特異的功能的基本接口,同時也負責FSocket對象的創建,域名解析等其它功能。
通常情況下,下一步就可以是各個平臺的FSocket 和ISocketSubsystem的派生實現了,但是,考慮到幾乎所有操作系統都實現了BSD socket API,所以先加了一層FSocketBSD和FSocketSubsystemBSD,也是在這里,兩者產生了直接引用,FSocketBSD保存了一個ISocketSubsystem指針。這一層其實已經實現了絕大部分的功能。
再往后就是每個平臺的繼承和實現,大多數只是Subsystem部分的Create(),Init()等操作,部分的FSocketBSD有繼承下來改動Multi相關的操作。
ISocketSubsystem::Get()獲取不同平臺的單例ISocketSubsystem實例,在其上進一步調用CreateSocket創建FSocket.
UE4 采用Module來管理不同的平臺ISocketSubsystem的創建和銷毀。FSocketSubsystemWindows調用CreateSocketSubsystem和DestroySocketSubsystem來創建和銷毀子系統。這兩個函數extern 聲明在SocketSubsystem.cpp中,而對應對每個平臺的Subsystem類的cpp文件中都實現了這兩個函數.
因此,Socket模塊總的使用流程是:
Reference:
- UE 4.23 Sockets模塊源碼.
總結
以上是生活随笔為你收集整理的ue4集合类型_UE4-Sockets的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: electron 打包把node代理服务
- 下一篇: 文件标识符必须为双精度类型的整数值标量_