UDN
Search public documentation:

TcpLinkCH
English Translation
日本語訳
한국어

Interested in the Unreal Engine?
Visit the Unreal Technology site.

Looking for jobs and company info?
Check out the Epic games site.

Questions about support via UDN?
Contact the UDN Staff

UE3 主页 > 输入 / 输出 > TcpLink

TcpLink


概述


TcpLink 类允许您在虚幻引擎中创建 TCP 套接字。通过这个套接字,您可以和因特网上的其它服务器相连接,或者您可以提供一个简单的网络服务。

注意,这不是一个具有高性能的功能。使用这个功能会对游戏性能产生重大的影响。当提供服务时,性能影响会更大。所以当时用这个功能时请记住这点。

在页面的底部,您会看到一些使用 TcpLink 的几个实例。

引擎内部包含了一个 HTTP WebServer 的实现。这个网络服务器使用了 TcpLink 接功能。

模式


这个 TcpLink 类包含了几个控制这个类作用的模式。这些模式如下所示:

Receive mode(接收模式)

当接收数据时 TcpLink 可以以两种不同的模式进行操作:

  • Event mode(事件模式)(RMODE_Event)
  • Manual mode(手动模式)(RMODE_Manual)

Event mode(事件模式)

在事件模式中,TcpLink 连接的 native 代码将会根据连接模式触发其中的一个事件。

MODE_Text 模式中,执行 ReceivedText 事件。_text_ 参数包含了自从上一个事件后接收到的所有文本。

MODE_Line 模式中,执行 ReceivedLine 事件。_line_ 参数包含了单独的一行文本,没有行终结符号。和其它的事件不同,这个事件在每次 tick(更新)中可以发生多次。

MODE_Binary 模式中,执行 ReceivedBinary 事件。_count_ 参数说明了在字节缓冲 B 中允许的字节数。

Manual mode(手动模式)

正如它的名称所预示的,在手动模式中,您负责读取数据。这可以通过在一个 tick(更新)事件期间或者使用一个计时器来完成。我们强烈地推荐您不要在每次 tick(更新)时执行多次读取操作,因为这样会减慢并阻挡操作。

可以使用 ReadTextReadBinary 函数来读取数据。这两个函数返回了读取的字节的数量。_ReadBinary_ 的参数 count 定义了您可以读取的字节的最大数量。您可以使用它的返回值来决定可以读取的字节的实际数量。

与事件模式不同,它和连接模式是没有关系的。您可以使用任何函数。您可以使用轻量级的 IsDataPending 函数,来看看您是否觉着读取数据很麻烦。

Link mode(连接模式)

在 TcpLink 中可以操作两种不同的模式。连接模式决定了当在接收模式事件模型中 TcpLink 操作时将要调用哪个事件。

连接模型也影响了 SendText 的工作方式。当连接模型是 MODE_Line 时,那么将会在使用 SendText 发送的文本后面添加换行结束符。请参照行模式部分来获得关于换行结束符的信息。

Line mode(行模式)

行模式控制了当接收到文本时如何检测新加的行,并且控制在 SendText 上添加新建行的结束符。仅当连接模式设置为 MODE_Line 时才会使用行模式。

需要为发送模式 ( OutLineMode ) 和接收模式 ( InLineMode ) 分别地设置行模式。

模式 结束符  
LMODE_DOS \n\r  
LMODE_UNIX \n  
LMODE_MAC \r\n 不能使用。它是不争去的,和旧的 MacOS 使用的 \r 一样。
LMODE_AUTO \n\r 当接收数据时,会在 \n 处对其进行分个,并且会删除 \r 的前面和后面的字符串。

连接状态


TcpLink 包含了一个用于报告当前连接状态的变量: LinkState 。通常您不需要关系这个,特别是当您使用 TcpLink 的事件时。但是有些情况下,使用它来获取当前正在发生的事情或许是有趣的。

STATE_Initialized
TcpLink 的初始状态。它已经准备好进行绑定。您可以使用 BindPort
STATE_Ready
TcpLink 被绑定到一个端口,并且准备好建立连接。您可以使用 OpenListen
STATE_Listening
TcpLink 监听正在到来的连接。这通常是调用 Listen 的结果。
STATE_Connecting
正在尝试连接。这通常是调用 Open 的结果。TcpLink 还没有准备好进行 I/O(输入/输出)。
STATE_Connected
已经建立了连接,准备好进行 I/O(输入/输出)。
STATE_ListenClosePending
Listen(监听)套接字排队等待被关闭。这通常是调用 Close 的结果。
STATE_ConnectClosePending
客户端套接字排队等待被关闭。这通常是调用 Close 的结果。
STATE_ListenClosing
listen(监听)套接字当前正在关闭它的连接。它还不能用于做其它事情。
STATE_ConnectClosing
客户端套接字正在关闭它的连接。它还不能用于做其它事情。

应用


TcpLink 类可以使用两种不同的方式进行应用,作为客户端或作为服务器。

客户端

  1. 设置适当的模式。
  2. BindPort()
  3. 创建 IpAddr 结构: * 通过使用 Resolve(...) 解析主机名称。 * 使用 StringToIpAddr(..) 来转换 IP 字符串。
  4. Open(..)
  5. 1. 等待 Opened() 事件、或者当 LinkStateSTATE_Connected 时、或等 IsConnected() 返回真时。
  6. 读 和/或 写 数据
  7. Close(..)

客户端通常会随机地使用一个空闲接口,因此在调用 BindPort 时不必使用任何参数。

请参照下面链接的包中的 TcpLinkClient 类来获得关于如何使用 TcpLink 作为客户端的实例。

服务器

为服务器使用 TcpLink 稍微有点复杂。我们强烈推荐您把服务器分为两个类:

  1. 一般的监听类
  2. 连接接受类

一般的监听类将会简单地监听连接尝试及当建立了一个连接时生成一个连接接受类。实际上是连接接受类真正地负责处理连接。这个逻辑已经内置到了 TcpLink 类中,您所做的一切便是设置 AcceptClass 变量。

监听类的过程如下:

  1. 设置适当的模式。
  2. 设置监听类。
  3. BindPort(12345)
  4. Listen()
  5. [可选项] 向 GainedChild(..)LostChild(..) 事件做出反应。

服务器应该在特定的端口上进行监听,否则客户端不知道它们应该连接到哪个端口上。那个端口已经绑定到了某些其它的过程上的情况也是可能发生的。在这种情况下, BindPort(..) 将会返回值 0,意味着没有绑定端口。另外,您可以设置第二个参数为真,这样它将绑定到下一个可用端口上。绑定端口是通过函数调用 BindPort(..) 返回的。当绑定成功后,您可以调用 Listen() 函数来启动服务器。

当定义一个 AcceptClass 类,并建立了一个新的连接时将会调用 GainedChild(..)LostChild(..) 事件。您可以使用这个功能来限制可以连接到服务器上的最大数量。要想停止接受新的连接,您可以简单地调用 Close() 函数,要想重新启动接受连接只要简单地再次调用 Listen() 函数即可。

当建立连接后,连接接受类和客户端套接字的工作方式是非常像的。

  1. 等待 Accepted 事件
  2. 读 和/或 写 数据
  3. Close(..)

当没有设置 AcceptClass 时,监听类将接受每个连接的客户端的 Accepted 事件。

API


结构

IpAddr

这是由 IP 地址 (IPv4) 和端口数组成。

变量

LinkMode
请参照链接模式
InLineMode , OutLineMode
请参照线模式
Port
本地端口
ReceiveMode
请参照 Receive(接收)模式
LinkState
请参照 Link(连接)状态
RemoteAddr
包含另一侧机器信息的 IpAddr 结构
AcceptClass
用于服务器模式中,因为这个类将会处理连入的连接

除了这里列出的变量外还有一些其它变量,但是这些变量是在内部使用的,从而应该遗弃。

函数

IsDataPending

native function bool IsDataPending()

如果套接字上的数据是没有处理的,则返回真。

ParseURL

native function bool ParseURL(coerce string URL, out string Addr, out int PortNum, out string LevelName, out string EntryName)

解析 Unreal URL。如果是有效的 url 则返回真。Unreal 的 URL 和您在浏览器中使用的 URL 是不同的。它可能不是非常有用。

Resolve

native function Resolve( coerce string Domain )

解析作为第一个参数提供的主机名称。主机名称解析是一个较慢的过程,因此函数的结果是通过一个事件返回的。

当解析成功时,调用 Resolved 。否则调用 ResolveFailed 事件。

GetLastError

native function int GetLastError()

返回最近的错误代码。返回值 0 的意思是没有错误。其它的值的意思由底层子系统决定。 对于 MS Windows 来说,错误的代码与 WinSock API 是等同的。

IpAddrToString

native function string IpAddrToString( IpAddr Arg )

将 IpAddr(IP 地址)结构转化为字符串。例如: 123.123.123.123:45678

StringToIpAddr

native function bool StringToIpAddr( string Str, out IpAddr Addr )

将 IPv4 地址 + 端口解析为 IpAddr 结构。当成功时返回真。

GetLocalIP

native function GetLocalIP(out IpAddr Arg )

获得本地 IP 地址。这是由底层子系统返回的第一个 IP 地址,并且它可能是一个不可路由的地址。所以请小心使用它。

BindPort

native function int BindPort( optional int PortNum, optional bool bUseNextAvailable )

为这个 TcpLink 实例绑定一个端口。如果没有给出端口号,那么分配随机的空闲端口。如果第二个参数位置,那么如果最佳的端口已经被使用,则绑定下一个可用的空闲端口。如果它为 false,那么绑定失败。

返回值是绑定端口,否则绑定失败返回 0。

Listen

native function bool Listen()

设置 TcpLink 的监听模式。如果成功返回真。在监听模式中,TcpLink 将会等待将要到来的连接。请参照服务器模式获得更多的信息。

Open

native function bool Open( IpAddr Addr )

打开一个到远程主机的连接。使用 StringToIpAddrResolve 来获得有效的 IpAddr 结构。

如果在初始化连接时出现问题,那么返回假。当调用这个函数后,套接字还没有准备好连接。请等待 Opened 事件出现或当 IsConnected 变为真时才准备好。

Close

native function bool Close()

关闭当前的连接。请使用这个函数来停止 TcpLink 监听将要连入的连接,或者关闭到远程主机的连接。当关闭连接后,您可以使用 OpenClose 来重新打开连接。

IsConnected

native function bool IsConnected()

当 TcpLink 连接到远程主机时返回真。在客户端模式中,当建立了到远程主机的有效连接时返回真。在服务器模式中仅当连接了客户端时才返回真。

SendText

native function int SendText( coerce string Str )

发送一个字符串到远程主机。如果连接模式是 MODE_Line ,那么将会附加一个行结束符。请参照服务器模式获得更多的信息。

它将会返回发送到远程主机的字节的数量,这可能和字符串的长度不一致。

SendBinary

native function int SendBinary( int Count, byte B[255] )

发送一些字节到远程主机。_count_ 参数定义了缓冲(第二个参数)中要发送到远程主机的字节的数量。您可以一次最多发送 255 个字节。

它将会返回发送到远程主机的字节的数量。

ReadText

native function int ReadText( out string Str )

从远程主机读取文本。这是一个阻塞操作,直到数据读取完成为止将不会返回。这个函数仅在手动传递模式中使用。

它返回了读取的字节的数量,它不是必须等于字符串长度。

ReadBinary

native function int ReadBinary( int Count, out byte B[255] )

可以从远程主机读取的字节的最大数量。此时您可以最多读取 255 个字节。这个函数仅在手动传递模式中使用。

它返回了读取的字节的数量。这个值可以小于 count 参数中提供的值。

事件

Resolved(解析)

event Resolved( IpAddr Addr )

当成功解析了一个主机名称时调用它。

ResolveFailed

event ResolveFailed()

当不能解析主机名称时调用它。

Accepted(接受)

event Accepted()

当客户端连接到监听模式中的一个 TcpLink 时调用,或者由在监听模式中的一个 TcpLink 产生的 TcpLink 调用。

Opened

event Opened()

open 成功时调用。

Closed

event Closed()

当关闭 TcpLink 连接时调用。这是或者是调用 close 的结果或者是当远程主机关闭连接时的结果。

ReceivedText

event ReceivedText( string Text )

当连接模式是 MODE_Text 并且接收模式是 RMODE_Event 的情况下,TcpLink 接收文本时调用这个函数。

ReceivedLine

event ReceivedText( string Line )

当连接模式是 MODE_Line 并且接收模式是 RMODE_Event 的情况下,TcpLink 接收文本时调用这个函数。会根据线模式将文本从新行中分离出来。每次更新时可以多次调用这个事件。

ReceivedText

event ReceivedBinary( int Count, byte B[255] )

当连接模式是 MODE_Binary 并且接收模式是 RMODE_Event 的情况下,TcpLink 接收文本时调用这个函数。_count_ 参数定义了写入到字节缓冲中的字节数量。

下载


压缩文件中包含的是几个关于 TcpLink 类应用的实例:

TcpLinkClient
一个非常简单的 HTTP 客户端。
TcpLinkServer
一个简单的服务器,它将会回应它接收到的的每行文本,这个过程实际上是由 TcpLinkServerAcceptor 类处理的。
TcpLinkServerAcceptor
这个类处理 TcpLinkServer 接收到的连接。