Ios Swift 3流委托偶数处理程序错误

Ios Swift 3流委托偶数处理程序错误,ios,swift,sockets,delegates,flush,Ios,Swift,Sockets,Delegates,Flush,我正在编写一个非常简单的TCP套接字应用程序,用于从服务器发送和接收数据;我的应用程序使用代理;我从网上找到的大部分代码,但流的事件处理程序都没有工作;你知道为什么永远不会调用下面的方法吗 更新:此问题已在此处得到回答: 但是,我面临的问题是,在缓冲区已满后,如何刷新输出流?我想将数据实时发送到我的服务器,但由于流输出错误,我得到了一个“断管” /** NSStream Delegate Method where we handle errors, read and write data f

我正在编写一个非常简单的TCP套接字应用程序,用于从服务器发送和接收数据;我的应用程序使用代理;我从网上找到的大部分代码,但流的事件处理程序都没有工作;你知道为什么永远不会调用下面的方法吗

更新:此问题已在此处得到回答:

但是,我面临的问题是,在缓冲区已满后,如何刷新输出流?我想将数据实时发送到我的服务器,但由于流输出错误,我得到了一个“断管”

/**
 NSStream Delegate Method where we handle errors, read and write data from input and output streams

 :param: stream NStream that called delegate method
 :param: eventCode      Event Code
 */
final func stream(stream: Stream, handleEvent eventCode: Stream.Event) {
    switch eventCode {
    case Stream.Event.endEncountered:
        endEncountered(stream: stream)

    case Stream.Event.errorOccurred:
        print("[SCKT]: ErrorOccurred: \(stream.streamError?.localizedDescription)")

    case Stream.Event.openCompleted:
        print("open completed")
        openCompleted(stream: stream)

    case Stream.Event.hasBytesAvailable:
        handleIncommingStream(stream: stream)

    case Stream.Event.hasSpaceAvailable:
        print("space available")
        writeToStream()

    default:
        print("default!")
    }
}
UIViewController

import Darwin
import Foundation
import UIKit
import Dispatch

class ViewController: UIViewController {

    @IBOutlet private weak var joystickMove: Joystick!
    @IBOutlet private weak var joystickRotate: Joystick!

    private var joystick = Joystick()
    private var contour = Contours()
    private var contour_index: Int = 0

    private var ip_address = "000.000.00.0" as CFString
    private var port: Int = 0000

    private var control_socket: Socket

    //    private var control_socket: Socket = Socket()

    private var toast_label: UILabel = UILabel()

    //    let dataProcessingQueue = DispatchQueue.main

    //    convenience init() {
    //        self.control_socket = Socket()
    //    }

    //    init(coder aDecoder: NSCoder!) {
    //        super.init(coder: aDecoder)
    //    }

    //    init(imageURL: NSURL?) {
    //        self.control_socket = Socket()
    //        self.control_socket.open(host: self.ip_address as String!, port: self.port)
    //        super.init(nibName: nil, bundle: nil)
    //    }

//    required init?(coder aDecoder: NSCoder) {
//        fatalError("init(coder:) has not been implemented")
//    }

    required init(coder aDecoder: NSCoder) {
        print("here!")
        self.control_socket = Socket()
//        self.control_socket.open(host: self.ip_address as String!, port: self.port)
        print("here(2)!")
        super.init(coder: aDecoder)!
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        self.control_socket.open(host: self.ip_address as String!, port: self.port)

        createJoystick()
        createContours()
        createViewsButton()
        recvLidarData()
    }

    private func requestIsComplete() -> Bool {
        // This function should find out if all expected data was received and return 'true' if it did.
        return true
    }

    private func processData(data: Data) {
        // This function should do something with the received data
    }

    private func recvLidarData() {
        let concurrentQueue = DispatchQueue(label: "queuename", attributes: .concurrent)
        concurrentQueue.async {
            // recieve the data here!
        }
    }

    private func createToast() {
        self.toast_label = UILabel(frame: CGRect(x: self.view.frame.size.width/2 - 150, y: self.view.frame.size.height-100, width: 300, height: 35))
        self.toast_label.backgroundColor = UIColor.black
        self.toast_label.textColor = UIColor.white
        self.toast_label.textAlignment = NSTextAlignment.center;
        self.view.addSubview(self.toast_label)
        self.toast_label.text = "Could not connect to server"
        self.toast_label.alpha = 1.0
        self.toast_label.layer.cornerRadius = 10;
        self.toast_label.clipsToBounds  =  true
        UIView.animate(withDuration: 4.0, delay: 0.1, options: UIViewAnimationOptions.curveEaseOut, animations: {
            self.toast_label.alpha = 0.0
        })
    }

    private func createJoystick() {

        let n: CGFloat = 100.0
        let x: CGFloat = (UIScreen.main.bounds.width/2) - (n/2.0)
        let y: CGFloat = UIScreen.main.bounds.height - (UIScreen.main.bounds.height/4.0)

        self.joystick.frame = CGRect(x: x, y: y, width: n, height: n)
        self.joystick.backgroundColor =  UIColor.clear

        self.joystick.substrateColor = UIColor.lightGray
        self.joystick.substrateBorderColor = UIColor.gray
        self.joystick.substrateBorderWidth = 1.0
        self.joystick.stickSize = CGSize(width: 50.0, height: 50.0)
        self.joystick.stickColor = UIColor.darkGray
        self.joystick.stickBorderColor = UIColor.black
        self.joystick.stickBorderWidth = 2.0
        self.joystick.fade = 0.5

        self.joystick.ip_address = self.ip_address
        self.joystick.port = self.port

        var packet = ""

        DispatchQueue.global(qos: .userInitiated).async { // do some task

            //            self.control_socket = Socket()
            //            self.control_socket.open(host: self.ip_address as String!, port: self.port)

            self.joystick.trackingHandler = { (data) -> () in

                var power = sqrt(pow(Double(data.velocity.x), 2.0) + pow(Double(data.velocity.y), 2.0))
                let theta = atan2(Double(-data.velocity.y), Double(data.velocity.x))
                let degrees = theta * (180.0 / M_PI)

                power = power/1.2

                if degrees >= 55 && degrees <= 125 { // move forward
                    packet = "\(1) \(1) \(power) \(power)"
                } else if degrees >= -125 && degrees <= -55 { // move backwards
                    packet = "\(-1) \(-1) \(power) \(power)"
                } else if degrees >= -55 && degrees <= 55 { // turn right
                    packet = "\(1) \(-1) \(power) \(power)"
                } else { // turn left
                    packet = "\(-1) \(1) \(power) \(power)"
                }

            }

            print("packet: \(packet)")

            self.control_socket.send(message: packet)

            print("sent")
        }

        view.addSubview(joystick)
    }

    private func createContours() {
        let n: CGFloat = 350.0
        let x: CGFloat = (UIScreen.main.bounds.width/2.0) - (n/2.0)
        let y: CGFloat = UIScreen.main.bounds.height - (UIScreen.main.bounds.height/4.0) - n - 100.0
        self.contour.frame = CGRect(x: x, y: y, width: n, height: n)
        self.contour.backgroundColor = UIColor.clear
        view.addSubview(self.contour)
    }

    private func createViewsButton() {
        let width: CGFloat = 150.0
        let height: CGFloat = 75.0
        let x: CGFloat = (UIScreen.main.bounds.width/2.0) - (width/2.0)
        let y: CGFloat = UIScreen.main.bounds.height - (UIScreen.main.bounds.height/4.0) - width

        let button: UIButton = UIButton(frame: CGRect(x: x, y: y, width: width, height: height))
        button.backgroundColor = UIColor.blue
        button.setTitle("Contour Views", for: .normal)
        button.addTarget(self, action: #selector(self.buttonAction), for: .touchUpInside)
        button.tag = 1
        view.addSubview(button)
    }

    @objc private func buttonAction(sender: UIButton!) {
        var btnsendtag: UIButton = sender
        if btnsendtag.tag == 1 {
            self.contour_index = (self.contour_index + 1) % 2
            switch self.contour_index {
            case 0:
                for index in 0...356 {
                    if self.contour.distx[index] != -1 && self.contour.disty[index] != -1 {
                        self.contour.circles[index].alpha = 0
                    }
                }
            case 1:
                for index in 0...356 {
                    if self.contour.distx[index] != -1 && self.contour.disty[index] != -1 {
                        self.contour.circles[index].alpha = 1
                    }
                }
            default:
                for index in 0...356 {
                    if self.contour.distx[index] != -1 && self.contour.disty[index] != -1 {
                        self.contour.circles[index].alpha = 1
                        UIColor.cyan.setFill()
                        self.contour.lines[index].fill()
                        self.contour.lines[index].stroke()
                    }
                }
            }

        }
    }

    override func viewDidAppear(_ animated: Bool) {
    }

    public func delayWithSeconds(_ seconds: Double, completion: @escaping () -> ()) {
        DispatchQueue.main.asyncAfter(deadline: .now() + seconds) {
            completion()
        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    override func viewWillDisappear(_ animated: Bool) {
    }
}
导入达尔文
进口基金会
导入UIKit
进口发货
类ViewController:UIViewController{
@IBOutlet private var joystickMove:操纵杆!
@IBOutlet private Vr joystickRotate:操纵杆!
专用变量操纵杆=操纵杆()
私有变量等高线=等高线()
私人var等值线指数:Int=0
私有变量ip_address=“000.000.00.0”作为CFString
专用变量端口:Int=0000
专用var控制\u套接字:套接字
//私有变量控制\u套接字:套接字=套接字()
私有变量toast_label:UILabel=UILabel()
//让dataProcessingQueue=DispatchQueue.main
//便利初始化(){
//self.control_socket=socket()
//    }
//init(编码器aDecoder:NSCoder!){
//super.init(编码者:aDecoder)
//    }
//初始化(imageURL:NSURL?){
//self.control_socket=socket()
//self.control\u socket.open(主机:self.ip\u地址为String!,端口:self.port)
//super.init(nibName:nil,bundle:nil)
//    }
//必需的初始化?(编码器aDecoder:NSCoder){
//fatalError(“初始化(编码者:)尚未实现”)
//    }
必需的初始化(编码器aDecoder:NSCoder){
打印(“这里!”)
self.control_socket=socket()
//self.control\u socket.open(主机:self.ip\u地址为String!,端口:self.port)
打印(“此处(2)!”)
super.init(编码器:aDecoder)!
}
重写func viewDidLoad(){
super.viewDidLoad()
self.control\u socket.open(主机:self.ip\u地址为String!,端口:self.port)
创建操纵杆()
createContours()
createViewsButton()
recvLidarData()
}
private func requestIsComplete()->Bool{
//此函数应查明是否收到所有预期数据,如果收到,则返回“true”。
返回真值
}
专用func processData(数据:数据){
//此函数应该对接收到的数据进行处理
}
私有函数recvLidarData(){
让concurrentQueue=DispatchQueue(标签:“queuename”,属性:。并发)
concurrentQueue.async{
//在这里接收数据!
}
}
私有函数createToast(){
self.toast_label=UILabel(帧:CGRect(x:self.view.frame.size.width/2-150,y:self.view.frame.size.height-100,宽度:300,高度:35))
self.toast_label.backgroundColor=UIColor.black
self.toast_label.textColor=UIColor.white
self.toast_label.textAlignment=NSTextAlignment.center;
self.view.addSubview(self.toast\u标签)
self.toast\u label.text=“无法连接到服务器”
self.toast_label.alpha=1.0
self.toast_label.layer.cornerRadius=10;
self.toast_label.clipstobunds=true
UIView.animate(持续时间:4.0,延迟:0.1,选项:UIViewAnimationOptions.curveEaseOut,动画:{
self.toast_label.alpha=0.0
})
}
私有函数{
设n:CGFloat=100.0
设x:CGFloat=(UIScreen.main.bounds.width/2)-(n/2.0)
设y:CGFloat=UIScreen.main.bounds.height-(UIScreen.main.bounds.height/4.0)
self.mogage.frame=CGRect(x:x,y:y,宽度:n,高度:n)
self.mogage.backgroundColor=UIColor.clear
self.mogage.substrateColor=UIColor.lightGray
self.mogage.substrateBorderColor=UIColor.gray
self.mogage.substrateBorderWidth=1.0
self.mogage.stickSize=CGSize(宽度:50.0,高度:50.0)
self.mogage.stickColor=UIColor.darkGray
self.mogage.StickOrderColor=UIColor.black
self.maggage.StickOrderWidth=2.0
self.magnage.fade=0.5
self.mogage.ip_地址=self.ip_地址
self.mogage.port=self.port
var packet=“”
DispatchQueue.global(qos:.userInitiated).async{//执行一些任务
//self.control_socket=socket()
//self.control\u socket.open(主机:self.ip\u地址为String!,端口:self.port)
self.magnage.trackingHandler={(数据)->()在
var功率=sqrt(功率(双倍(data.velocity.x),2.0)+功率(双倍(data.velocity.y,2.0))
设θ=atan2(Double(-data.velocity.y),Double(data.velocity.x))
设度数=θ*(180.0/M_π)
功率=功率/1.2
如果度>=55&°rees=-125&°rees=-55&°rees()){
DispatchQueue.main.asyncAfter(截止日期:.now()+秒){
完成()
}
}
重写函数didReceiveMemoryWarning(){
超级。我收到了记忆警告()
//处置所有可以重新创建的资源。
}
覆盖函数视图将消失(u动画:Bool){
}
}
插座类

import UIKit
import Foundation

@objc protocol SocketStreamDelegate{
    func socketDidConnect(stream:Stream)
    @objc optional func socketDidDisconnet(stream:Stream, message:String)
    @objc optional func socketDidReceiveMessage(stream:Stream, message:String)
    @objc optional func socketDidEndConnection()
}

class Socket: NSObject, StreamDelegate {

    var delegate:SocketStreamDelegate?

    private let bufferSize = 1024
    private var _host:String?
    private var _port:Int?
    private var _messagesQueue:Array<String> = [String]()
    private var _streamHasSpace:Bool = false
    private var inputStream: InputStream?
    private var outputStream: OutputStream?

    var isClosed = false
    var isOpen = false

    var host:String?{
        get{
            return self._host
        }
    }

    var port:Int?{
        get{
            return self._port
        }
    }

    deinit{
        if let inputStr = self.inputStream{
                        inputStr.close()
                        inputStr.remove(from: .main, forMode: RunLoopMode.defaultRunLoopMode)
        }
        if let outputStr = self.outputStream{
                        outputStr.close()
                        outputStr.remove(from: .main, forMode: RunLoopMode.defaultRunLoopMode)
        }
    }

    /**
     Opens streaming for both reading and writing, error will be thrown if you try to send a message and streaming hasn't been opened

     :param: host String with host portion
     :param: port Port
     */
    final func open(host:String!, port:Int!){
        self._host = host
        self._port = port

        var inStreamUnmanaged:Unmanaged<CFReadStream>?
        var outStreamUnmanaged:Unmanaged<CFWriteStream>?

        CFStreamCreatePairWithSocketToHost(nil, host as CFString!, UInt32(port), &inStreamUnmanaged, &outStreamUnmanaged)

        inputStream = inStreamUnmanaged?.takeRetainedValue()
        outputStream = outStreamUnmanaged?.takeRetainedValue()

        if inputStream != nil && outputStream != nil {

            inputStream!.delegate = self
            outputStream!.delegate = self

            //            var myloop = RunLoop.current

            //            inputStream!.schedule(in: myloop, forMode: RunLoopMode.defaultRunLoopMode)
            //            outputStream!.schedule(in: myloop, forMode: RunLoopMode.defaultRunLoopMode)

            inputStream!.schedule(in: .main, forMode: RunLoopMode.defaultRunLoopMode)
            outputStream!.schedule(in: .main, forMode: RunLoopMode.defaultRunLoopMode)

            print("[SCKT]: Open Stream")

            self._messagesQueue = Array()

            inputStream!.open()
            outputStream!.open()

            //            myloop.run()

            print("Run")

        } else {
            print("[SCKT]: Failed Getting Streams")
        }
    }

    final func close(){
        if let inputStr = self.inputStream {
            inputStr.delegate = nil
            inputStr.close()
            inputStr.remove(from: .main, forMode: RunLoopMode.defaultRunLoopMode)
        }
        if let outputStr = self.outputStream {
            outputStr.delegate = nil
            outputStr.close()
            outputStr.remove(from: .main, forMode: RunLoopMode.defaultRunLoopMode)
        }
        isClosed = true
    }

    /**
     NSStream Delegate Method where we handle errors, read and write data from input and output streams

     :param: stream NStream that called delegate method
     :param: eventCode      Event Code
     */
    final func stream(stream: Stream, handleEvent eventCode: Stream.Event) {
        switch eventCode {
        case Stream.Event.endEncountered:
            endEncountered(stream: stream)

        case Stream.Event.errorOccurred:
            print("[SCKT]: ErrorOccurred: \(stream.streamError?.localizedDescription)")

        case Stream.Event.openCompleted:
            print("open completed")
            openCompleted(stream: stream)

        case Stream.Event.hasBytesAvailable:
            handleIncommingStream(stream: stream)

        case Stream.Event.hasSpaceAvailable:
            print("space available")
            writeToStream()

        default:
            print("default!")
        }
    }

    final func endEncountered(stream: Stream) {

    }

    final func openCompleted(stream: Stream){
        if(self.inputStream!.streamStatus == .open && self.outputStream!.streamStatus == .open) {
            let justAOneTimeThing: () = {
                self.isOpen = true
                self.delegate!.socketDidConnect(stream: stream)
            }()
        }
    }

    /**
     Reads bytes asynchronously from incomming stream and calls delegate method socketDidReceiveMessage
     :param: stream An NSInputStream
     */
    final func handleIncommingStream(stream: Stream) {

        if stream is InputStream {

            var buffer = [UInt8](repeating: 0, count: bufferSize)

            DispatchQueue.global(qos: .userInitiated).async {

                let len = self.inputStream?.read(&buffer, maxLength: buffer.count)

                if len! >= 0 {
                    if let output = NSString(bytes: &buffer, length: len!, encoding: String.Encoding.utf8.rawValue) {
                        self.delegate?.socketDidReceiveMessage!(stream: stream, message: output as String)
                    }
                } else {
                    // Handle error
                }
            }
        } else {
            print("[SCKT]: \(#function) : Incorrect stream received")
        }
    }

    /**
     If messages exist in _messagesQueue it will remove and it and send it, if there is an error
     it will return the message to the queue
     */
    final func writeToStream() {
        if _messagesQueue.count > 0 && self.outputStream!.hasSpaceAvailable  {
            DispatchQueue.global(qos: .userInitiated).async {
                let message = self._messagesQueue.removeLast()
                let buff = [UInt8](message.utf8)
                if self.outputStream!.write(buff, maxLength: buff.count) == -1 {
                    self._messagesQueue.append(message)
                }
            }
        }
    }

    final func send(message:String){
        _messagesQueue.insert(message, at: 0)
        writeToStream()
    }
}
导入UIKit
进口基金会
@objc协议SocketStreamDelegate{
func socketDidConnect(流:流)
@objc可选函数socketdidisconnet(流:流,消息:字符串)
@objc可选函数socketDidReceiveMessage(流:流,消息:字符串)
@objc可选函数socketDidEndConnection()
}
类套接字:NSObject,StreamDelegate{
变量委托:SocketStreamDelegate?
私有let bufferSize=1024
私有变量\u主机:字符串?
专用变量\u端口:Int?
私人v
final func stream(stream: Stream, handleEvent eventCode: Stream.Event)
func stream(_ aStream: Stream, handle eventCode: Stream.Event)