socket服务器在iOS端,可以用BSD Socket + CFNetwork + Stream + NetService实现。
首先用BSD Socket创建socket -> 绑定-> 监听
fd4 = socket(AF_INET, SOCK_STREAM, 0)//创建ipv4 socket
//绑定
let sockaddrIn = sockaddr_in(sin_len: __uint8_t(MemoryLayout<sockaddr_in>.size), sin_family: sa_family_t(AF_INET), sin_port: CFSwapInt16HostToBig(8888), sin_addr: in_addr(s_addr: INADDR_ANY), sin_zero: (0, 0, 0, 0, 0, 0, 0, 0))
let sockaddrPtr = withUnsafePointer(to: sockaddrIn) { (ptr) in
return ptr.withMemoryRebound(to: sockaddr.self, capacity: 1, { (p) -> UnsafePointer<sockaddr> in
return p
})
}
err = bind(fd, sockaddrPtr, socklen_t(sockaddrIn.sin_len))
//监听
err = listen(fd4, 1024)
用 CFNetwork 把BSD Socket的socket 转成CFNetwork的socket 创建runloopsource -> 添加runloopsource
let ptr = UnsafeMutableRawPointer.allocate(byteCount: MemoryLayout<ViewController>.size, alignment: MemoryLayout<ViewController>.alignment)
ptr.storeBytes(of: self, as: ViewController.self)
var context = CFSocketContext(version: 0, info: ptr, retain: nil, release: nil, copyDescription: nil)
ipv4Socket = CFSocketCreateWithNative(kCFAllocatorDefault, fd, CFSocketCallBackType.acceptCallBack.rawValue, { (sock, type, data, rawPtr, info) in
//回调
info?.bindMemory(to: ViewController.self, capacity: 1).pointee.listeningSocketCall(sock: sock, type: type, address: data, data: rawPtr)
}, &context)
if ipv4Socket != nil {
let socketsource = CFSocketCreateRunLoopSource(kCFAllocatorDefault, ipv4Socket, 0)
assert(socketsource != nil)
CFRunLoopAddSource(CFRunLoopGetCurrent(), socketsource, CFRunLoopMode.defaultMode)
}
在回调方法里面 创建 readStream 和 writeStream -> 设置流代理 -> 打开流
CFStreamCreatePairWithSocket(kCFAllocatorDefault, fd, cfreadStreamPtr, cfwriteStreamPtr)
readStream = cfreadStreamPtr.pointee?.takeRetainedValue()
writeStream = cfwriteStreamPtr.pointee?.takeRetainedValue()
readStream.setProperty(kCFBooleanTrue, forKey: Stream.PropertyKey(kCFStreamPropertyShouldCloseNativeSocket as String))
writeStream.setProperty(kCFBooleanTrue, forKey: Stream.PropertyKey(kCFStreamPropertyShouldCloseNativeSocket as String))
readStream.schedule(in: RunLoop.current, forMode: .default)
readStream.delegate = self
writeStream.schedule(in: RunLoop.current, forMode: .default)
writeStream.delegate = self
readStream.open()
writeStream.open()
最后用 NetService 创建服务
netService.schedule(in: RunLoop.current, forMode: .default)
netService.delegate = self
netService.publish()