LoginSignup
3
4

More than 5 years have passed since last update.

【Swift3.0】【Xcode8】【iOS10】 socketのbindでエラー

Posted at

ほぼ自分用のメモでごめんなさい。

はじめに

iOSで例えば簡易HTTPサーバとか作ろうとすると割に面倒っぽいです。私が知らないだけの可能性も高いのですが、NSなんちゃらでそれっぽいのを探すことが出来ませんでした。

そこでgithubとか漁ってみますと、いくつかありました。HTTPサーバとなるとswifterとかが良さげに見えます。で中見るとお馴染みのsocketなAPIでよしなにしている感じでした。あーじゃあライブラリ理解するのも面倒だし、自分でもやれるなーと思って組んでみた訳です。

ところがbindでエラー

最近xcode8とかiOS10、Swift3になった関係か、いろいろと怒られまくりました。多くはxcode様のお導きで勝手に直っていったのですが、以下のコードだけがどうにもエラーから先に進みません。コード自体はswifterのを見ながら組んだ感じなのです。

var addr = sockaddr_in(sin_len: UInt8(strideof(sockaddr_in)),
             sin_family: UInt8(AF_INET),
             sin_port: port.bigEndian,
             sin_addr: in_addr(s_addr: in_addr_t(0)),
             sin_zero:(0, 0, 0, 0, 0, 0, 0, 0))

 let bindResult = withUnsafePointer(to: &addr) {
    bind(socketFileDescriptor, UnsafePointer<sockaddr>($0),
        socklen_t(MemoryLayout<sockaddr_in>.size))
}

上記のbindがこんな感じで怒られるのです。withMemoryReboundとかSwift初心者にはかなり厳しそう(滝汗)

'init' is unavailable: use 'withMemoryRebound(to:capacity:_)' to temporarily view memory as another layout-compatible type.

これでOK

socket系になると私のスキルではAppleDevelopperサイトから情報を引き出すのは難しかったです(お恥ずかしい話です)。

で、答えはstackoverflowにありました。どうもポインタ系の修正が必要になるみたいです。つまりはエラーメッセージの通りではあるのですが…。stackoverflowに従って以下のように記載することでパスりました(一応Xcodeに言われたような方法でなおしてみました)

var addr = sockaddr_in(sin_len: UInt8(strideof(sockaddr_in)),
             sin_family: UInt8(AF_INET),
             sin_port: port.bigEndian,
             sin_addr: in_addr(s_addr: in_addr_t(0)),
             sin_zero:(0, 0, 0, 0, 0, 0, 0, 0))

let bindResult = withUnsafePointer(to: &addr) {
    $0.withMemoryRebound(to: sockaddr.self, capacity: 1) {
        bind(socketFileDescriptor, $0,
            socklen_t(MemoryLayout<sockaddr_in>.stride))
    }
}

bind以外はそれほど大したこともなく、シミュレータレベルですが、bindした後accept出来ることをiPhone7/iOS10で確認できました。いやーSwiftでメモリ操作なんて、C++で「;」をしょっちゅう忘れてしまう私にはハードルが高い高い(なぜか涙が…)

ただこれ、swifterとか大丈夫なのかなーとは思いました。

おわりに

stackoverlow様には(いつもではありますが)もう感謝です。

(一応)上記のコードはパブリックドメインとします。当然ですが使用した際の損害は誰も請け負ってくれません。そこだけ注意願います。

以上です。

3
4
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4