浏览器上的 GCDAsyncSocket 立即连接和断开连接,并出现“远程对等方关闭套接字”错误
Posted
技术标签:
【中文标题】浏览器上的 GCDAsyncSocket 立即连接和断开连接,并出现“远程对等方关闭套接字”错误【英文标题】:GCDAsyncSocket on browser connects and disconnects immediately with "Socket closed by remote peer" error 【发布时间】:2014-11-13 23:14:51 【问题描述】:我对网络编程和第一次使用 GCDAsyncSocket 非常陌生。我正在尝试实现一个 ios 应用程序,其中 1 个设备充当主机,其他设备(浏览器)连接到它。我正在使用 NSNetService/NSNetServiceBrowser 发布/浏览部分。
现在,我的客户端/浏览器正确解析主机地址并尝试使用以下代码连接到它:
func netServiceDidResolveAddress(sender: NSNetService)
// Connect with Service
if (self.connectWithService(sender, hostname: sender.hostName!))
println("Connecting with service: domainName= \(sender.domain), type= \(sender.type), name= \(sender.name), onPort= \(sender.port) and hostname: \(sender.hostName!)");
else
println("Unable to connect with service: domainName= \(sender.domain), type= \(sender.type), name= \(sender.name), onPort= \(sender.port)");
private func connectWithService(service: NSNetService, hostname: String) ->Bool
var isConnecting:Bool = false;
if (self.browserSocket == nil || !(self.browserSocket?.isConnected)!)
// Initialize Socket
self.browserSocket = GCDAsyncSocket(delegate: self, delegateQueue: dispatch_get_main_queue());
// Connect
while (!isConnecting)
var error: NSError?;
println("Connecting port : \(service.port) and hostname: \(hostname)");
if (self.browserSocket.connectToHost(hostname, onPort: UInt16(service.port), error: &error))
isConnecting = true;
else if (error != nil)
println("Unable to connect to address. Error \(error) with user info \(error?.userInfo)");
else
println("Connecting is: \(self.browserSocket.isConnected)");
isConnecting = self.browserSocket.isConnected;
return isConnecting;
// GCDAsyncSocketDelegate methods
func socket(sock: GCDAsyncSocket!, didConnectToHost host: String!, port: UInt16)
println("Socket: \(sock) Did connect to host: \(host) on port:\(port)");
// Start Reading
sock.readDataToLength(UInt(sizeof(UInt64)), withTimeout: -1.0, tag: 0);
func socketDidDisconnect(sock: GCDAsyncSocket!, withError err: NSError!)
println("Socket \(sock) did disconnect with error \(err?)");
以下是发布者代码:
覆盖 func viewDidLoad()
super.viewDidLoad()
let barButton = UIBarButtonItem(title: "Stop Publishing", style: .Done, target: self, action: "stopPublishing");
self.navigationItem.rightBarButtonItem = barButton;
// Publish the service
self.publishService();
// MARK: Button callbacks
private func publishService()
// Initialize GCDAsyncSocket
self.socket = GCDAsyncSocket(delegate: self, delegateQueue: dispatch_get_main_queue());
// Start listening for incoming connections
var error: NSError?;
if (self.socket.acceptOnPort(0, error: &error))
// Initialize Service
self.service = NSNetService(domain: "local.", type: "_mpstest._tcp", name: UIDevice.currentDevice().name, port:0);
// Configure Service
self.service.delegate = self;
self.service.includesPeerToPeer = true;
self.service.publishWithOptions(.ListenForConnections);
else
println("Unable to create socket. Error \(error?.description) with user info \(error?.userInfo)");
现在,客户端与主机连接并点击以下方法:
func socket(sock: GCDAsyncSocket!, didConnectToHost host: String!, port: UInt16)
但随后它立即断开与 ErrorCode =7 "Socket closed by remote peer" 的以下方法的连接
func socketDidDisconnect(sock: GCDAsyncSocket!, withError err: NSError!)
以下是来自浏览器设备的控制台日志:
Service found is : <NSNetService 0x15e2f710> local. _mpstest._tcp. iPad 30
Connecting port : 50797 and hostname: iPad-30.local.
Connecting with service: domainName= local., type= _mpstest._tcp., name= iPad 30, onPort= 50797 and hostname: iPad-30.local.
Socket <GCDAsyncSocket: 0x15d80020> did disconnect with error Optional(Error Domain=kCFStreamErrorDomainNetDB Code=8 "nodename nor servname provided, or not known" UserInfo=0x15e3c7a0 NSLocalizedDescription=nodename nor servname provided, or not known)
Connecting port : 50797 and hostname: iPad-30.local.
Connecting with service: domainName= local., type= _mpstest._tcp., name= iPad 30, onPort= 50797 and hostname: iPad-30.local.
Socket: <GCDAsyncSocket: 0x15e59c20> Did connect to host: 169.254.78.98 on port:50797
Socket <GCDAsyncSocket: 0x15e59c20> did disconnect with error Optional(Error Domain=GCDAsyncSocketErrorDomain Code=7 "Socket closed by remote peer" UserInfo=0x15e5b070 NSLocalizedDescription=Socket closed by remote peer)
永远不会命中主机套接字委托方法。
我真的被困在这里了。关于我在这里做错了什么的任何帮助都会很棒。
谢谢 维克
【问题讨论】:
在 Objective C 中也有同样的问题:***.com/q/27419679/2225439 我遇到了完全相同的问题。由于这已经有几个月了,你有没有设法解决这个问题?如果是这样,我会喜欢一个提示:) 【参考方案1】:我也有同样的错误!经过大量搜索并拔出头发后,我偶然发现了一个与 GCDAsyncSocket 的弱声明有关的解决方案,Swift 中的 ARC 将 GCDAsyncSocket.m 中的声明“__weak”理解为尽快释放套接字的借口。
在您的项目中搜索关键字“__weak”并删除所有引用。 在以下位置找到此解决方案:Delegate not getting set
【讨论】:
收到第一个请求的响应后,Socket 断开连接。以上是关于浏览器上的 GCDAsyncSocket 立即连接和断开连接,并出现“远程对等方关闭套接字”错误的主要内容,如果未能解决你的问题,请参考以下文章