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