iOS中的TCP流与调度
我必须建立一个应用程序,也将能够接收和发送数据。 我需要创建至少两个线程。一个可以持续监听和响应接口并发送数据的接口iOS中的TCP流与调度,ios,swift,dispatch-async,Ios,Swift,Dispatch Async,我必须建立一个应用程序,也将能够接收和发送数据。 我需要创建至少两个线程。一个可以持续监听和响应接口并发送数据的接口 var a = connectionClass() @IBOutlet weak var textField: UITextField! @IBAction func myButton(sender: AnyObject) { a.sendData() } override func viewDidLoad() { super.viewDidLoad()
var a = connectionClass()
@IBOutlet weak var textField: UITextField!
@IBAction func myButton(sender: AnyObject) {
a.sendData()
}
override func viewDidLoad() {
super.viewDidLoad()
let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
dispatch_async(dispatch_get_global_queue(priority, 0), { ()->() in
print("gcd hello")
dispatch_async(dispatch_get_main_queue(), {
self.a.initNetworkCommunication()
print("hello from UI thread executed as dispatch")
})
})
print("hello from UI thread")
}
此代码锁定用户界面,但它正在接收数据。
我正在寻找解决方案,或者说例子,在那里我可以看到我的问题的解决方案
为了创建流,我使用了以下代码:
=========================================================================
好了,开始工作了。我可以打开连接并发送数据。
但现在我不知道如何使用其他类的函数来读取流。
如何创建self.a.stream
流(aStream:NSStream,handleEvent事件代码:NSStreamEvent)
从我不知道如何使用event和如何初始化NSString开始。
我知道,这是个愚蠢的问题,但对我来说很复杂
视图控制器:
导入UIKit
类ViewController:UIViewController、NSStreamDelegate{
var a = connectionClass()
@IBOutlet weak var textField: UITextField!
@IBAction func myButton(sender: AnyObject) {
a.sendData()
}
override func viewDidLoad() {
super.viewDidLoad()
dispatch_async(dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0), { ()->() in
print("Inicjalizowanie")
self.a.initNetworkCommunication()
dispatch_async(dispatch_get_main_queue(), {
print("hello from UI thread executed as dispatch")
})
})
print("hello from UI thread")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
连接类别:
进口基金会
类connectionClass:NSObject,NSStreamDelegate{
override init(){
}
//deklaracja podstawowych zmiennych
private let serverAddress: CFString = "someIp"
private let serverPort: UInt32 = 10001
private var inputStream: NSInputStream!
private var outputStream: NSOutputStream!
var i = 0
//Inicjalizacja połączenia
func initNetworkCommunication() {
//zmienne potrzebne do pobierania i wysyłania danych
var readStream: Unmanaged<CFReadStream>?
var writeStream: Unmanaged<CFWriteStream>?
//tworzy stream
autoreleasepool {
CFStreamCreatePairWithSocketToHost(nil, self.serverAddress, self.serverPort, &readStream, &writeStream)
}
self.inputStream = readStream!.takeRetainedValue()
self.outputStream = writeStream!.takeRetainedValue()
//delegaty w SWIFT - doczytać
self.inputStream.delegate = self
self.outputStream.delegate = self
//tworzy pętlę dla połączenia - doczytać
self.inputStream.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)
self.outputStream.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)
self.inputStream.open()
self.outputStream.open()
print("Zainicjalizowane")
}
//co ta funkcja robi i gdzie jest używana. Czy ona oczekuje na wywołanie połączenia z serwerem?
func stream(aStream: NSStream, handleEvent eventCode: NSStreamEvent) {
print("a tu jest stream")
switch eventCode{
case NSStreamEvent.OpenCompleted:
print("Otwarto połączenie")
break
case NSStreamEvent.HasSpaceAvailable:
if outputStream == aStream{
print("Połączenie jest gotowe")
break
}
case NSStreamEvent.HasBytesAvailable:
print("Są ramki")
if aStream == inputStream{
var buffer: UInt8 = 0
var len: Int!
while (inputStream?.hasBytesAvailable != nil) {
len = inputStream?.read(&buffer, maxLength: 32)
if len > 0 {
let output = buffer
print("Server odpowiedział: \(output)")
}
}
}
break
case NSStreamEvent.ErrorOccurred:
print("Nie można połączyć się z serwerem!")
break
case NSStreamEvent.EndEncountered:
outputStream.close()
outputStream.removeFromRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)
outputStream = nil
default:
print("Nieznane działanie ")
}
}
func sendData() {
let data = NSData(bytes: [0x0F, 0x00, 0x10, 0x00, 0x00, 0x80, 0x55, 0x00, 0x55, 0x04, 0x00, 0x01, 0x00, 0x00, 0xB2, 0x04 ] as [UInt8], length: 16)
outputStream?.write(UnsafePointer<UInt8>(data.bytes) , maxLength: data.length)
print("wysłano: \(data)")
}
override init(){
}
//德克拉拉贾·波德斯塔沃维奇·兹米恩尼奇
私有let服务器地址:CFString=“someIp”
专用let服务器端口:UInt32=10001
私有变量输入流:NSInputStream!
私有变量outputStream:NSOutputStream!
变量i=0
//伊尼贾利扎卡·波希尼亚
func initNetworkCommunication(){
//兹米安·波兹本·波比亚尼亚和维西亚尼亚·达尼奇
var readStream:非托管?
var writeStream:非托管?
//双流
自动释放池{
CFStreamCreatePairWithSocketToHost(nil、self.serverAddress、self.serverPort、readStream和writeStream)
}
self.inputStream=readStream!.takeRetainedValue()
self.outputStream=writeStream!.takeRetainedValue()
//代表团w斯威夫特-doczytać
self.inputStream.delegate=self
self.outputStream.delegate=self
//tworzy pętlędla połączenia-doczytać
self.inputStream.scheduleInRunLoop(NSRunLoop.currentRunLoop(),格式:NSDefaultRunLoopMode)
self.outputStream.scheduleInRunLoop(NSRunLoop.currentRunLoop(),格式:NSDefaultRunLoopMode)
self.inputStream.open()
self.outputStream.open()
打印(“Zainicjalizowane”)
}
//我和罗比一起开玩笑。你是不是在开玩笑?
函数流(aStream:NSStream,handleEvent事件代码:NSStreamEvent){
印刷品(“一个笑话流”)
开关事件代码{
案例nsstreamvent.OpenCompleted:
印刷品(“Otwarto połączenie”)
打破
案例nsstreamvent.HasSpaceAvailable:
如果outputStream==aStream{
印刷品(“Połączenie jest gotowe”)
打破
}
案例nsstreamvent.hasbytes可用:
印刷品(“Sąramki”)
如果aStream==inputStream{
变量缓冲区:UInt8=0
瓦伦:Int!
while(inputStream?.hasbytes可用!=nil){
len=inputStream?读取(&缓冲区,最大长度:32)
如果len>0{
让输出=缓冲区
打印(“服务器odpowiedzia:\(输出)”)
}
}
}
打破
发生NSStreamEvent.Error的情况:
印刷品(“Nie można połączyćsięz serwerem!”)
打破
案例NSStreamEvent.EndEncounted:
outputStream.close()
outputStream.removeFromRunLoop(NSRunLoop.currentRunLoop(),格式:NSDefaultRunLoopMode)
outputStream=nil
违约:
印刷品(“Nieznane działanie”)
}
}
func sendData(){
让数据=NSData(字节:[0x0F,0x00,0x10,0x00,0x00,0x80,0x55,0x00,0x55,0x04,0x00,0x01,0x00,0x00,0xB2,0x04]作为[UInt8],长度:16)
outputStream?.write(非安全指针(data.bytes),maxLength:data.length)
打印(“wysłano:\(数据)”)
}
}
首先:不需要线程来执行异步IO。IO可以通过运行循环上的GCD进行调度。这是一个很好的介绍: 第二:我不确定您的
dispatch\u async
code部分想要实现什么。它只是在一个辅助线程中运行print
。然后你把你的self.a.initNetworkCommunication
放回到主线程上
第三:查看ChatClientSwift中的代码,a.sendData()
似乎在执行阻塞写入。那,好吧,街区
有相当多的Swift GCD套接字库可用。这是一个:,还有更多。你可能想看看这种情况。为什么不使用AFNetworking这样的框架,或者你不能在主线程中发送阻塞网络代码呢?你有没有收到任何错误,或者它只是冻结了?你能提供任何调试信息吗?我正在试图找出你在哪里阻止了主线程。我已经下载了SwiftSockets并试图构建它,但它是用Swift 3之前的Swift版本编写的。我越是试图修改它,无论有没有编辑转换和自动修复,我得到的错误就越多。我对Mac和Swift完全陌生,所以这可能是问题的一部分。无论如何,如果您能推荐一些其他最新的教程和/或结合Swift 3、GCD和TCP套接字的开源项目,我将不胜感激。我一片空白。。。谢谢。在继续我之前的评论时,我现在在GitHub上找到了这个项目:它是最新的(Swift 3,目前每天提交几次),并且为套接字提供了一个纯Swift包装器。它本身并不使用GCD,但在“ReadMe”中有一个测试程序,显示了如何在用Swift编写的调用程序中使用GCD。