Получение ответа от TCP-сервера на клиенте Swift

Я пытаюсь написать клиент сокета TCP в swift, используя GCDAsyncSocket, но у меня есть одна проблема. В моем коде у меня есть NSTextField (называется box) и вот мой код:

import Cocoa

class AppDelegate: NSObject, NSApplicationDelegate 
{

    @IBOutlet weak var window: NSWindow!
    @IBOutlet weak var box: NSTextField!

    var bsocket: GCDAsyncSocket!

    func applicationDidFinishLaunching(aNotification: NSNotification?)
    {
        bsocket = GCDAsyncSocket(delegate: self, delegateQueue: dispatch_get_main_queue())
        var port:UInt16 = 8090
        if (!bsocket.connectToHost("localhost", onPort: port, error: nil))
        {
            println("Error")
        }
        else
        {
            println("Connecting...")
        }
        var request:String = "Arn.Preg:3302:"
        var data:NSData = request.dataUsingEncoding(NSUTF8StringEncoding)!
        bsocket.writeData(data, withTimeout: -1.0, tag: 0)
        bsocket.readDataWithTimeout(-1.0, tag: 0)
    }

    func applicationWillTerminate(aNotification: NSNotification?) 
    {
        // Insert code here to tear down your application
    }

    func socket(socket : GCDAsyncSocket, didReadData data:NSData, withTag tag:UInt16)
    {
        var response = NSString(data: data, encoding: NSUTF8StringEncoding)
        println("Received Response")
        box.stringValue = box.stringValue + "\n" + response
    }

    func socket(socket : GCDAsyncSocket, didConnectToHost host:String, port p:UInt16)
    {
        println("Connected to \(host) on port \(p).")
        box.stringValue = box.stringValue + "\n" + "Connected to \(host) on port \(p)."
    }
}

func socket(socket : GCDAsyncSocket, didReadData data:NSData, withTag tag:UInt16)

Когда я использую команду telnet в терминале, чтобы попытаться получить доступ к моему TCP-серверу, это результат.

Marzuk:~ marzukrashid$ telnet localhost 8090
Trying ::1...
telnet: connect to address ::1: Connection refused
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Arn.TipoSer:XPL0:

Затем, когда я набираю "Arn.Preg:3302:", сервер возвращает это:

Marzuk:~ marzukrashid$ telnet localhost 8090
Trying ::1...
telnet: connect to address ::1: Connection refused
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Arn.TipoSer:XPL0:
Arn.Preg:3302:
Arn.Resp:3302=329351:

Когда я набираю "Arn.Preg: 3302:" сервер возвращает "Arn.Resp:3302=329351:", это результат, которого я пытаюсь достичь, я хочу, чтобы NSTextField в моем приложении отображал "Arn.Resp:3302=329351:". Прямо сейчас, когда я запускаю свой код, программа регистрирует "Соединение...", "Подключено к 127.0.0.1 через порт 8090" и "Полученный ответ", как это должно быть, и в NSTextField в самом приложении, на нем отображается "Подключено к 127.0.0.1 через порт 8090". и "Arn.TipoSer:XPl0:", как и должно быть, но он не отображает "Arn.Resp:3302=329351:", как я хочу это тоже.

Мой вопрос: почему мой код этого не делает, и как я могу исправить свой код в этом.

Благодарю.

2 ответа

Решение

Я узнал, что функция didReadData запускается только при запуске функции readDataWithTimeout, поэтому я добавил функцию readDataWithTimeout в didConnectToHost, didReadData и applicationDidFinishLaunching. Я узнал, что "\n" требуется в конце запроса, чтобы дать нажатие клавиши возврата, используемой в терминале, поэтому я добавил "\n" к "Arn.Preg:3302:", чтобы сделать это "Arn.Preg:3302:\ п". Окончательный код выглядел так:

import Cocoa

class AppDelegate: NSObject, NSApplicationDelegate {

    @IBOutlet weak var window: NSWindow!
    @IBOutlet weak var box: NSTextField!


    //let bsocket = GCDAsyncSocket(delegate: AppDelegate.self, delegateQueue: dispatch_get_main_queue())
    var bsocket: GCDAsyncSocket!

    func applicationDidFinishLaunching(aNotification: NSNotification?)
    {
        bsocket = GCDAsyncSocket(delegate: self, delegateQueue: dispatch_get_main_queue())
        var port:UInt16 = 8090
        if (!bsocket.connectToHost("localhost", onPort: port, error: nil))
        {
            println("Error.")
        }
        else
        {
            println("Connecting...")
        }
        bsocket.readDataWithTimeout(-1.0, tag: 0)
    }

    func applicationWillTerminate(aNotification: NSNotification?) {
        // Insert code here to tear down your application
    }

    func socket(socket : GCDAsyncSocket, didReadData data:NSData, withTag tag:UInt16)
    {
        var response = NSString(data: data, encoding: NSUTF8StringEncoding)
        println("Received Response")
        box.stringValue = box.stringValue + "\n" + response
        bsocket.readDataWithTimeout(-1.0, tag: 0)
    }

    func socket(socket : GCDAsyncSocket, didConnectToHost host:String, port p:UInt16)
    {
        println("Connected to \(host) on port \(p).")
        box.stringValue = box.stringValue + "\n" + "Connected to \(host) on port \(p)."
        bsocket.readDataWithTimeout(-1.0, tag: 0)
        sendRequest()
    }

    func sendRequest()
    {
        var request:String = "Arn.Preg:3302:\n"
        var data:NSData = request.dataUsingEncoding(NSUTF8StringEncoding)!
        bsocket.writeData(data, withTimeout: -1.0, tag: 0)
    }

}

Мне кажется, вы пытаетесь отправить Arn.Preg:3302: сообщение и получить ответ, прежде чем вы на самом деле подключился. В вашем applicationDidFinishLaunching Вы инициируете асинхронное соединение, а затем немедленно вызываете writeData а также readData - вам, вероятно, нужно сделать что-то вроде:

class AppDelegate: NSObject, NSApplicationDelegate 
{

    @IBOutlet weak var window: NSWindow!
    @IBOutlet weak var box: NSTextField!

    var bsocket: GCDAsyncSocket!

    func applicationDidFinishLaunching(aNotification: NSNotification?)
    {
        bsocket = GCDAsyncSocket(delegate: self, delegateQueue: dispatch_get_main_queue())
        var port:UInt16 = 8090
        if (!bsocket.connectToHost("localhost", onPort: port, error: nil))
        {
            println("Error")
        }
        else
        {
            println("Connecting...")
        }
    }

    func socket(socket : GCDAsyncSocket, didReadData data:NSData, withTag tag:UInt16)
    {
        var response = NSString(data: data, encoding: NSUTF8StringEncoding)
        println("Received Response")
        box.stringValue = box.stringValue + "\n" + response
    }

    func socket(socket : GCDAsyncSocket, didConnectToHost host:String, port p:UInt16)
    {
        println("Connected to \(host) on port \(p).")
        box.stringValue = box.stringValue + "\n" + "Connected to \(host) on port \(p)."

        var request:String = "Arn.Preg:3302:"
        var data:NSData = request.dataUsingEncoding(NSUTF8StringEncoding)!
        bsocket.writeData(data, withTimeout: -1.0, tag: 0)
        bsocket.readDataWithTimeout(-1.0, tag: 0)
    }
}
Другие вопросы по тегам