从Swift客户端上的TCP服务器获取响应

时间:2014-09-08 20:24:34

标签: xcode sockets tcp swift gcdasyncsocket

我正在尝试使用GCDAsyncSocket在swift中编写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 :&#34 ;.现在,当我运行我的代码时,程序会记录"正在连接......","在端口8090上连接到127.0.0.1。"和"收到响应& #34;,应该在应用程序本身的NSTextField中显示"在端口8090上连接到127.0.0.1。"和#34; Arn.TipoSer:XPl0:"应该如此,但它没有显示" Arn.Resp:3302 = 329351:"我也想要它。

我的问题是为什么我的代码没有这样做,以及如何修复我的代码。

感谢。

2 个答案:

答案 0 :(得分:2)

我了解到didReadData函数仅在运行readDataWithTimeout函数时运行,因此我将readDataWithTimeout函数添加到didConnectToHost,didReadData和applicationDidFinishLaunching。我了解到了" \ n"在请求结束时需要给出终端中使用的返回击键,所以我添加了" \ n"到" Arn.Preg:3302:"制作它" 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)
    }

}

答案 1 :(得分:0)

对我而言,您似乎在尝试发送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)
    }
}