xcode 从 Swift 客户端上的 TCP 服务器获取响应
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25732590/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Getting Response from TCP server on Swift client
提问by Marzukr
I am trying to write a TCP socket client in swift using GCDAsyncSocket, but I have one problem. In my code I have a NSTextField (called box) and here is my code:
我正在尝试使用 GCDAsyncSocket 快速编写一个 TCP 套接字客户端,但我有一个问题。在我的代码中,我有一个 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)
When I use the telnet command in the terminal to try to access my TCP server, this is the result.
当我在终端中使用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:
Then, when I type in "Arn.Preg:3302:", the server returns this:
然后,当我输入“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:
When I type in "Arn.Preg:3302:" the server returns "Arn.Resp:3302=329351:", this is the result I am trying to achieve, I want the NSTextField in my application to display "Arn.Resp:3302=329351:". Right now, when I run my code, the program logs "Connecting...", "Connected to 127.0.0.1 on port 8090.", and "Received Response", as it should, and in the NSTextField in the application itself, it displays "Connected to 127.0.0.1 on port 8090." and "Arn.TipoSer:XPl0:" as it should, but it is not displaying "Arn.Resp:3302=329351:" as I want it too.
当我输入“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:"。
My question is why is my code not doing this, and how can I fix my code into doing this.
我的问题是为什么我的代码不这样做,我该如何修复我的代码来做到这一点。
Thanks.
谢谢。
回答by Marzukr
I have learned that the didReadData function only runs when the readDataWithTimeout function is run, so I added the readDataWithTimeout function to the didConnectToHost, didReadData, and applicationDidFinishLaunching. I learned that a "\n" is required at the end of the request to give the return keystroke used in the terminal, so I added "\n" to the "Arn.Preg:3302:" to make it "Arn.Preg:3302:\n". The final code looked like this:
我了解到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)
}
}
回答by Nate Cook
To me it looks like you're trying to send the Arn.Preg:3302:
message and get a response before you've actually connected. In your applicationDidFinishLaunching
you initiate an asynchronous connection and then immediately call writeData
and readData
-- you probably need to do something like:
对我来说,您似乎正在尝试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)
}
}