网络编程

IP地址

import Darwin.POSIX.netinet.`in`

var addr = in_addr()
inet_pton(AF_INET, "127.0.0.1", &addr)
print(String(addr.s_addr, radix: 16)) // 01_00_00_7f

let ip = UnsafeMutableBufferPointer<CChar>.allocate(capacity: 4)
inet_ntop(AF_INET, &addr, ip.baseAddress, 16)
print(String(cString: ip.baseAddress!)) // 127.0.0.1

套接字

服务端

import Darwin.POSIX.sys.socket
import Darwin.POSIX.netdb

var hints = addrinfo()
hints.ai_family = AF_INET
hints.ai_socktype = SOCK_STREAM
hints.ai_protocol = IPPROTO_IP

var info: UnsafeMutablePointer<addrinfo>?
defer {
    if info != nil {
        freeaddrinfo(info)
    }
}

getaddrinfo(nil, "3000", &hints, &info)

var fd: Int32 = -1
while info != nil {
    fd = socket(info!.pointee.ai_family, info!.pointee.ai_socktype, info!.pointee.ai_protocol)
    
    if bind(fd, info!.pointee.ai_addr, info!.pointee.ai_addrlen) == 0 {
        break
    }
    
    info = info?.pointee.ai_next
}

listen(fd, 1000)

while true {
    var addr = sockaddr_in()
    var addrlen = socklen_t()
    
    let cfd = withUnsafeMutablePointer(to: &addr) {
        $0.withMemoryRebound(to: sockaddr.self, capacity: 1) {
            accept(fd, $0, &addrlen)
        }
    }
    
    let buffer = UnsafeMutableBufferPointer<CChar>.allocate(capacity: 30)
    defer {
        buffer.deallocate()
    }
    
    while recv(cfd, buffer.baseAddress, buffer.count, 0) != 0 {
        
        send(cfd, buffer.baseAddress, buffer.count, 0)
    }
    
    close(cfd)
}

客户端

import Darwin.POSIX.sys.socket
import Darwin.POSIX.netdb

var hints = addrinfo()
hints.ai_family = AF_INET
hints.ai_socktype = SOCK_STREAM
hints.ai_protocol = IPPROTO_IP

var info: UnsafeMutablePointer<addrinfo>?
defer {
    if info != nil {
        freeaddrinfo(info)
    }
}

getaddrinfo("127.0.0.1", "3000", &hints, &info)

var fd: Int32 = -1
while info != nil {
    fd = socket(info!.pointee.ai_family, info!.pointee.ai_socktype, info!.pointee.ai_protocol)
    
    if connect(fd, info!.pointee.ai_addr, info!.pointee.ai_addrlen) != -1 {
        break
    }
    
    info = info?.pointee.ai_next
}

while true {
    let buffer = UnsafeMutableBufferPointer<CChar>.allocate(capacity: 30)
    defer {
        buffer.deallocate()
    }
    
    fgets(buffer.baseAddress, Int32(buffer.count), stdin)
    
    send(fd, buffer.baseAddress, buffer.count, 0)
    
    recv(fd, buffer.baseAddress, buffer.count, 0)
    
    print(String(cString: buffer.baseAddress!))
}

close(fd)