2

多くの試行錯誤の後、成功せずに、これについて少し助けが必要なようです:

最新バージョンの Swift で sockaddr_in から IP アドレスとポート番号を取得するにはどうすればよいですか?

関連する質問をいくつか見ましたが、適切な例がどこにも見つからないようです。また、C 型の構造体とポインターを Swift でどのように処理する必要があるかを把握していないようです。これはあまり役に立ちません。

役に立つリソースへの例やリンクを教えてください。

よろしくお願いします!

4

1 に答える 1

4

IP アドレスとポートを数値として必要な場合は、対応するフィールドにsockaddr_in直接アクセスできますが、値をネットワーク バイト (ビッグ エンディアン) からホスト バイト オーダーに変換することを忘れないでください。

let saddr: sockAddr = ...

let port = in_port_t(bigEndian: sockAddr.sin_port)
let addr = in_addr_t(bigEndian: sockAddr.sin_addr.s_addr)

getnameinfo()を使用して、IP アドレスを文字列 (ドット付き 10 進数表記) として抽出し、オプションでポートも抽出できます。struct sockaddr_inポインターをポインターにキャストすることstruct sockaddrは、Swift では「再バインド」と呼ばれ、次のように行われwithMemoryRebound()ます。

var sockAddr: sockaddr_in = ...

var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST))
var service = [CChar](repeating: 0, count: Int(NI_MAXSERV))

withUnsafePointer(to: &sockAddr) {
    $0.withMemoryRebound(to: sockaddr.self, capacity: 0) {
        _ = getnameinfo($0, socklen_t($0.pointee.sa_len),
                        &hostname, socklen_t(hostname.count),
                        &service, socklen_t(service.count),
                        NI_NUMERICHOST | NI_NUMERICSERV)
    }
}
print("addr:", hostname)
print("port:", service)

これは、IPv4 と IPv6 の両方のソケット アドレス構造 (sockaddr_inおよびsockaddr_in6) で機能します。

「安全でないポインタ変換」の詳細については、 SE-0107 UnsafeRawPointer API およびUnsafeRawPointer Migrationを参照してください。後者のページには、Swift 3 でソケット アドレスを処理する方法のサンプル コードが含まれています。

于 2017-01-05T21:22:28.547 に答える