Swift 3 OutputStream已挂起?

问题描述 投票:1回答:1

我编写了一个简单的Swift程序来写入服务器;我想将数据背对背或循环发送到服务器;我尝试做一些简单的事情,我可以简单地将消息发送回(两个数据),但是挂起了;即服务器只接收第一条消息,而没有收到第二条消息。为什么会这样?

我正在Swift 3中使用StreamDelegate,并且正在使用OutputStream写入方法

print("Hello, World!")

import Foundation

class Connection: NSObject, StreamDelegate {

    private var inputStream: InputStream!
    private var outputStream: OutputStream!

    private var my_address: CFString
    private var my_port: UInt32

    init (address: CFString, port:UInt32) {
        self.my_address = address
        self.my_port = port
        super.init()
    }

    func connect() {
        print("connecting...")

        var readStream:  Unmanaged<CFReadStream>?
        var writeStream: Unmanaged<CFWriteStream>?

        CFStreamCreatePairWithSocketToHost(nil, self.my_address, self.my_port, &readStream, &writeStream)

        // Documentation suggests readStream and writeStream can be assumed to
        // be non-nil. It might be wise to test if either is nil
        // and implement error-handling as needed.

//        self.inputStream = readStream!.takeRetainedValue()
        self.outputStream = writeStream!.takeRetainedValue()

//        self.inputStream.delegate = self
        self.outputStream.delegate = self

//        self.inputStream.schedule(in: RunLoop.current, forMode: RunLoopMode.defaultRunLoopMode)
//        self.outputStream.schedule(in: RunLoop.current, forMode: RunLoopMode.defaultRunLoopMode)

//        self.inputStream.open()
        self.outputStream.open()
    }

    func disconnect() {
        self.inputStream.close()
        self.outputStream.close()
    }


    func stream(aStream: Stream, handleEvent eventCode: Stream.Event) {
        switch (eventCode){
        case Stream.Event.errorOccurred:
            NSLog("ErrorOccurred")
        case Stream.Event.endEncountered:
            NSLog("EndEncountered")
        case Stream.Event.hasBytesAvailable:
            NSLog("HasBytesAvaible")
            var buffer = [UInt8](repeating: 0, count: 4096)
            while (inputStream.hasBytesAvailable){
                var len = inputStream.read(&buffer, maxLength: buffer.count)
                if(len > 0){
                    var output = NSString(bytes: &buffer, length: buffer.count, encoding: String.Encoding.utf8.rawValue)
                    if (output != ""){
                        NSLog("server said: %@", output!)
                    }
                } else {
                    print("empty string from stream")
                }
            }
        case Stream.Event.openCompleted:
            NSLog("OpenCompleted")
        case Stream.Event.hasSpaceAvailable:
            NSLog("HasSpaceAvailable")
        default: print("default reached. unknown stream event")
        }
    }

    func sendMessage(message: String) {
        let buff = [UInt8](message.utf8)
        self.outputStream.write(buff, maxLength: buff.count)
    }

    func getOutputStream() -> OutputStream {
        return self.outputStream
    }



}

var socket = Connection(address: "000.000.0.000" as CFString, port: 0000)

socket.connect()

socket.sendMessage(message: "Hey you! 1")
socket.sendMessage(message: "Hey you! 2")

\

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 socket = Connection(address: "000.000.0.000" as CFString, port: 0000)

    override func viewDidLoad() {
        super.viewDidLoad()
        createJoystick()
        createContours()
        createButton()
    }

    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

        var packet = ""

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

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

                let 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)

                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 if (degrees >= 125 && degrees <= 180) && (degrees >= -180 && degrees <= -125) { // turn left
                    packet = "\(-1) \(1) \(power) \(power)"
                }

                self.socket.connect()

                let sent = self.socket.sendMessage(message: packet)

                if sent {
                    print("packet sent!\n \(packet)")
                }


                self.socket.stream(aStream: self.socket.inputStream, handleEvent: Stream.Event.hasBytesAvailable)

//                self.socket.changeWhenHasBytesAvailable = { str in
//                    print("my-str: \(str.characters)")
//                }

                self.socket.disconnect()
            }

        }

        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 createButton() {
        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) {
        DispatchQueue.global(qos: .background).async { // do some task
            //            self.socket.connect()
            //            var packet = "1 1 0 0"
            //            let sent = self.socket.sendMessage(message: packet)
            //            if sent {
            //                print("packet sent!\n \(packet)")
            //            }
            //            self.socket.disconnect()
        }
    }

    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) {
        //        self.socket.disconnect()
    }
}

\

import Foundation

class Connection: NSObject, StreamDelegate {

    public var inputStream: InputStream!
    private var outputStream: OutputStream!

    private var my_address: CFString
    private var my_port: UInt32

    public var changeWhenHasBytesAvailable: ((String)->())?

    init (address: CFString, port:UInt32) {
        self.my_address = address
        self.my_port = port
        super.init()
    }

    public func connect() {

        var readStream:  Unmanaged<CFReadStream>?
        var writeStream: Unmanaged<CFWriteStream>?

        CFStreamCreatePairWithSocketToHost(nil, self.my_address, self.my_port, &readStream, &writeStream)

        self.inputStream = readStream!.takeRetainedValue()
        self.outputStream = writeStream!.takeRetainedValue()

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

        self.inputStream.schedule(in: RunLoop.current, forMode: RunLoopMode.defaultRunLoopMode)
        self.outputStream.schedule(in: RunLoop.current, forMode: RunLoopMode.defaultRunLoopMode)

        self.inputStream.open()
        self.outputStream.open()

    }

    public func stream(aStream: Stream, handleEvent eventCode: Stream.Event) {

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

        print("stream")

        if aStream === self.inputStream {
            switch eventCode {

            case Stream.Event.openCompleted:
                print("open")
                break

            case Stream.Event.errorOccurred:
                print("error")
                break

            case Stream.Event.hasBytesAvailable:
                print("available!")

                //                    var inputBuffer = Array<UInt8>(repeating: 0, count:2048)
                //                    self.inputStream?.read(&inputBuffer, maxLength: 2048)
                //                    self.changeWhenHasBytesAvailable?(String(bytes: inputBuffer, encoding: String.Encoding.utf8)!)

                var buffer = [UInt8](repeating: 0, count: 512)
                while (self.inputStream.hasBytesAvailable){
                    print("before read")
                    var len = self.inputStream.read(&buffer, maxLength: buffer.count)
                    print("after read")
                    if(len > 0){
                        //                            var output = NSString(bytes: &buffer, length: buffer.count, encoding: String.Encoding.utf8.rawValue)
                        var output = NSString(bytes: &buffer, length: len, encoding: String.Encoding.utf8.rawValue)
                        if (output != ""){
                            print("output: \(output!)")

                        }
                    } else {
                        print("empty string from stream")
                    }
                    print("while")
                }

                break
            default:
                print("default")
                break
            }
        }
        //        }
    }

    public func sendMessage(message: String) -> Bool {
        var sent: Bool = false
        let buff = [UInt8](message.utf8)
        let result = self.outputStream.write(buff, maxLength: buff.count)

        if result != -1 {
            sent = true
        }
        return sent
    }

    public func disconnect() {
        self.inputStream.close()
        self.outputStream.close()

        //        self.inputStream.remove(from: RunLoop.current, forMode: RunLoopMode.defaultRunLoopMode)
        //        self.outputStream.remove(from: RunLoop.current, forMode: RunLoopMode.defaultRunLoopMode)
    }

}

更新;发送作品!但没有收到数据?

sockets tcp swift3 blocking outputstream
1个回答
0
投票

阅读时请不要在StreamDelegate中使用一会儿:

while (inputStream.hasBytesAvailable){
   var len = inputStream.read(&buffer, maxLength: buffer.count)
   ...
}

只需通话已读。如果还有更多字节,则将再次调用您的委托。

© www.soinside.com 2019 - 2024. All rights reserved.