【问题标题】:Getting Response from TCP server on Swift client从 Swift 客户端上的 TCP 服务器获取响应
【发布时间】:2014-09-10 07:17:13
【问题描述】:

我正在尝试使用 GCDAsyncSocket 快速编写一个 TCP 套接字客户端,但我遇到了一个问题。在我的代码中,我有一个 NSTextField(称为框),这是我的代码:

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:"。现在,当我运行我的代码时,程序会记录“正在连接...”、“已连接到端口 8090 上的 127.0.0.1。”和“收到的响应”,正如它应该在应用程序本身的 NSTextField 中一样,它显示“连接到端口 8090 上的 127.0.0.1”。和“Arn.TipoSer:XPl0:”,但它没有像我想要的那样显示“Arn.Resp:3302=329351:”。

我的问题是为什么我的代码不这样做,以及如何修复我的代码以执行此操作。

谢谢。

【问题讨论】:

  • 对不起,我忘了改代码,我刚刚编辑了。

标签: xcode sockets tcp swift gcdasyncsocket


【解决方案1】:

我了解到didReadData函数只有在readDataWithTimeout函数运行时才会运行,所以我在didConnectToHost、didReadData和applicationDidFinishLaunching中加入了readDataWithTimeout函数。我了解到在请求结束时需要一个“\n”来给出终端中使用的返回键,所以我在“Arn.Preg:3302:”中添加了“\n”以使其成为“Arn.Preg :3302:\n"。最终代码如下所示:

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

}

【讨论】:

    【解决方案2】:

    在我看来,您似乎是在尝试发送 Arn.Preg:3302: 消息并在实际连接之前获得回复。在您的applicationDidFinishLaunching 中,您启动一​​个异步连接,然后立即调用writeDatareadData——您可能需要执行以下操作:

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

    【讨论】:

    • 感谢帮助,但尝试后,结果是一样的。我也尝试将请求移至 didReadData 函数,但这也不起作用。
    猜你喜欢
    • 1970-01-01
    • 2015-05-11
    • 2018-12-02
    • 2022-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-18
    • 2018-12-30
    相关资源
    最近更新 更多