1. 程式人生 > >IBM-Swift/BlueSocket 一個為Swift而生的Socket框架

IBM-Swift/BlueSocket 一個為Swift而生的Socket框架

本文大體介紹了BlueSocket,大多數內容都有提及。(翻譯水平和理解水平有限,如有不對的地方請留言)
若想詳細瞭解BlueSocket請到文章尾部點選連結檢視原文。


Socket framework for Swift using the Swift Package Manager. Works on iOS, macOS, and Linux.
使用Swift包管理器的Swift Socket框架。適用於iOS,MacOS和Linux。
Generic low level socket framework. Pure Swift.
泛型低階套接字框架。純Swift。

使用條件

Swift

  • 支援Swift 3、Swift 4
  • xCode 9.0或更高版本

macOS

  • macOS 10.11.6 (El Capitan)或更高版本
  • xCode 8.3.2或更高版本
  • xCode 9.0或更高版本

iOS

  • iOS 10.0或更高版本
  • xCode 8.3.2或更高版本
  • xCode 9.0或更高版本

新增到專案的方法

CocoaPods

    platform :ios, '10.0'

    target 'MyApp' do
        use_frameworks!
        pod 'BlueSocket'
end

Carthage

github "IBM-Swift/BlueSocket" ~> <majorVersion>.<minor>

Swift Package Manager

    dependencies: [
        .Package(url: "https://github.com/IBM-Swift/BlueSocket.git", majorVersion: <majorVersion>, minor: <minor>)
    ]

使用前不要忘了添上這句

import Socket

Family, Type and Protocol Support

BlueSocket supports the following families, types and protocols:

Families:
    IPV4: Socket.ProtocolFamily.inet
    IPV6: Socket.ProtocolFamily.inet6
    UNIX: Socket.ProtocolFamily.unix
Types:
    Stream: Socket.SocketType.stream
    Datagram: Socket.SocketType.datagram
Protocols:
    TCP: Socket.SocketProtocol.tcp
    UDP: Socket.SocketProtocol.udp
    UNIX: Socket.SocketProtocol.unix

方法介紹

建立Socket

BlueSocket 提供了4種不同的構造方法用於建立一個Socket例項。

  1. create() —— 建立了一個全部為預設配置的Socket例項。(family為 .inet、type為 .stream、protocol為 .tcp)
  2. create(family family: ProtocolFamily, type: SocketType, proto: SocketProtocol) —— 建立一個自定義的Socket例項。
  3. create(connectedUsing signature: Signature) - This API will allow you create a Socket instance and have it attempt to connect to a server based on the information you pass in the Socket.Signature.
  4. create(fromNativeHandle nativeHandle: Int32, address: Address?) - This API lets you wrap a native file descriptor describing an existing socket in a new instance of Socket.

設定緩衝區大小

緩衝區預設大小為 Socket.SOCKET_DEFAULT_READ_BUFFER_SIZE (4096)
緩衝區最小值為 Socket.SOCKET_MINIMUM_READ_BUFFER_SIZE (1024)

下面展示瞭如何設定緩衝區大小,這裡省略了異常處理。

let mySocket = try Socket.create()
mySocket.readBufferSize = 32768

緩衝區的設定應在使用Socket例項前完成。

關閉Socket

close() - This function will perform the necessary tasks in order to cleanly close an open socket.

關閉Socket只需要呼叫此函式即可,呼叫此函式會執行一些必要的操作,以便徹底的關閉Socket,但是沒有提及必要的操作是什麼。

監聽Socket(TCP/UNIX)

使用以下方法來監聽Socket上的連線。

  1. listen(on port: Int, maxBacklogSize: Int = Socket.SOCKET_DEFAULT_MAX_BACKLOG, allowPortReuse: Bool = true) —— 第一個引數 port,指監聽哪一個埠。第二個引數 maxBackLogSize (BackLog:積壓),指設定等待連線的佇列的大小,預設值 Socket.SOCKET_DEFAULT_MAX_BACKLOG (50),在用作伺服器時此值可能還需要加大。第三個引數 allowPortReuse ,指的是是否允許複用埠,預設為true,允許重複使用監聽埠,若設定為false,當嘗試監聽一個正在使用中的埠時會報錯。
  2. listen(on path: String, maxBacklogSize: Int = Socket.SOCKET_DEFAULT_MAX_BACKLOG) —— 此函式只能用在UNIX上,引數意義同上,少了第三個引數。

下面例子建立了一個預設配置的Socket,且監聽了1337埠。這裡省略了異常處理。

var socket = try Socket.create()
try socket.listen(on: 1337)

接受連線請求(TCP/UNIX)

當偵聽的Socket檢測到有連線請求時,決策權在你的程式這裡。你可以選擇接受連線請求,或者選擇忽略連線請求繼續監聽,如果你的程式是多執行緒的你也可以一邊接受連線請求,一邊繼續監聽。BlueSocket提供兩種不同的方法來接受進來的連線請求。(1、2是第一種,3是第二種)

  1. acceptClientConnection(invokeDelegate: Bool = true) —— 接受連線請求並且返回一個新的Socket例項。正在監聽的例項不受影響。If invokeDelegate is false and the Socket has an SSLService delegate attached, you MUST call the invokeDelegateOnAccept method using the Socket instance that is returned by this function.
  2. invokeDelegateOnAccept(for newSocket: Socket) - If the Socket instance has a SSLService delegate, this will invoke the delegates accept function to perform SSL negotiation. It should be called with the Socket instance returned by acceptClientConnection. This function will throw an exception if called with the wrong Socket instance, called multiple times, or if the Socket instance does NOT have a SSLService delegate.
  3. acceptConnection() —— 這個方法接受進來的連線請求,替代並關閉現有的Socket監聽。當前Socket相關的屬性被新連線的Socket的屬性取代。

與伺服器建立Socket連線(TCP/UNIX)

除了上面提到的構造方法 create(connectedUsing:) 之外,BlueSocket 還提供了3個例項方法用於連線一個Socket例項到伺服器。

  1. connect(to host: String, port: Int32, timeout: UInt = 0) —— 此方法根據你提供的 hostname 與 port 來連線到伺服器。當提供的埠不在1-65535範圍內時會報錯。你可以選擇設定連線超時時間timeout,單位毫秒。當Socket處於阻塞模式時,且設定的timeout大於0時,Socket則暫時會變成非阻塞模式。返回的Socket將被設定回原來的設定(阻塞或非阻塞)。
  2. connect(to path: String) —— 此方法只能用於UNIX下。根據提供的path連線伺服器。
  3. connect(using signature: Signature) —— 此方法允許指定連線資訊,連線資訊包含在提供的Socket.Signature例項中。有關更多資訊,請參閱Socket.swift中的Socket.Signature。

從Socket讀取資料(TCP/UNIX)

BlueSocket 提供了4種從Socket讀取資料的方法,按推薦順序從上到下:

  1. read(into data: inout Data) —— 從Socket中讀取所有可用的資料,返回Data物件。
  2. read(into data: NSMutableData) —— 從Socket中讀取所有可用的資料,返回NSMutableData物件。
  3. readString() —— 從Socket中讀取所有可用的資料並將其作為字串返回,如果沒有資料可讀則返回nil。
  4. read(into buffer: UnsafeMutablePointer, bufSize: Int, truncate: Bool = false) —— 這個函式允許你通過提供一個不安全的指標將資料讀入指定大小的緩衝區,該緩衝區的大小由bufSize引數來設定。如果提供的緩衝區太小則會丟擲異常 Socket.SOCKET_ERR_RECV_BUFFER_TOO_SMALL,除非第三個引數truncate = ture,這種情況下Socket只讀取bufSize位元組的資料,未讀取到的資料將在下次呼叫時被讀取。如果truncate = false,你需要重新呼叫此函式並給出正確的bufSize。有關更多資訊,請參閱Error.bufferSizeNeeded in Socket.swift。

注意:
除readString()之外的所有讀取方法都可以返回零(0)。同時這可能表示遠端連線已關閉,或者可能表示Socket被阻塞了。(假設你已經關閉阻塞)為了區分關閉還是阻塞,可以檢查屬性remoteConnectionClosed,如果返回true,說明Socket遠端連線已關閉,而且這個Socket例項也應該關閉。

通過Socket傳送資料(TCP/UNIX)

BlueSocket 提供了4種傳送資料的方法,按推薦順序從上到下:

  1. write(from data: Data) —— 傳送Data型別資料。
  2. write(from data: NSData) —— 傳送NSData型別資料。
  3. write(from string: String) —— 傳送String型別資料。
  4. write(from buffer: UnsafeRawPointer, bufSize: Int) —— This function writes the data contained within the buffer of the specified size by providing an unsafe pointer to that buffer and an integer that denotes the size of that buffer.

UDP部分的不再介紹了。

有關NSData和NSMutableData的重要說明

上面使用NSData或NSMutableData的read、write方法在不久的將來可能會被棄用。

原文地址

https://github.com/IBM-Swift/BlueSocket