Swift2 でNSStreamを使ってソケット通信2(データ送信編)

前回の続き
データ送信は送信可能になった時にデータを送るだけでいけます。
データ変換処理の情報が少ないからそこはちょっと手間取るかも。








ソースコード



/** データ送信 */
func send(msg: String) {
 // 接続されていない場合接続
    if !isConnected {
        connect()
    }
    
    print("request is " + msg)
    // エンコード
    let request = msg.dataUsingEncoding(
                    NSShiftJISStringEncoding, 
                    allowLossyConversion: false)

    let requestBytes = UnsafePointer<uint8>(request!.bytes)
    let requestLength = request!.length
    
    // 書き込み可能になった送信
    var timeout = 5 * 100000 // wait 5 seconds before giving up
        while !self.outputStream.hasSpaceAvailable {
            usleep(1000) // wait until the socket is ready
            timeout -= 100
            if timeout < 0 {
                print("time out")
                self.delegate.didReceivedResponseData(Connection.ERR_MSG)
                return
            } else if self.outputStream.streamError != nil {
                print("disconnect Stream")
                self.delegate.didReceivedResponseData(Connection.ERR_MSG)
                return // disconnectStream will be called.
            }
        }
        // 送信可能になったら書き込む
        print("write")
        self.outputStream.write(requestBytes, maxLength: requestLength)
}

解説


接続処理が完了していることを前提にしています。
まずString型の送信データを送信用に変換します。
エンコーディングがUTF8だとうまく動作しなかった気が、要検証。

安定性を重視するために同期的に送信しています。
非同期にする場合はNSOperationQueue().addOperationWithBlock { [weak self] in ... で送信処理を囲めば実現できます。
outputStream.hasSpaceAvailable を参照して送信可能になるまでループしています。
一定時間が過ぎたらあるいはストリームエラーが発生したらエラーとして終了します。
書き込み可能になったらエンコードした送信データとデータサイズを引数にoutputStream.write メソッドを呼び出します。
サーバ側で受信が確認できれば成功です。


今日はここまで。

前回の記事
ソケット接続

次の記事
データ受信
まとめ

2016年9月23日金曜日