sockets - 浏览器上的 GCDAsyncSocket 连接并立即断开连接,出现 "Socket closed by remote peer"错误

标签 sockets swift network-programming ios8 gcdasyncsocket

我是网络编程的新手,也是第一次使用 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?)");

 }

以下是发布者代码:

覆盖函数 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})

主机套接字委托(delegate)方法永远不会被命中。

我真的被困在这里了。任何关于我在这里做错了什么的帮助都会很棒。

谢谢 维克

最佳答案

我也有同样的错误!经过大量搜索和摸索,我偶然发现了一个解决方案,该解决方案与 GCDAsyncSocket 的弱声明有关,Swift 中的 ARC 将 GCDAsyncSocket.m 中的声明“__weak”理解为尽快释放套接字的借口。

在您的项目中搜索关键字“__weak”并删除所有引用。 在以下位置找到此解决方案:Delegate not getting set

关于sockets - 浏览器上的 GCDAsyncSocket 连接并立即断开连接,出现 "Socket closed by remote peer"错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26920250/

相关文章:

node.js - 如何使用socket.io和NodeJS关闭所有套接字

ios - Swift:返回 UItable View 委托(delegate)和数据源

ios - 以编程方式获取导航栏的高度

Objective-C 发起/恢复 wifi 连接

c - linux C编程获取Client IP总是获取0.0.0.0

delphi - 从 120 更新到 Indy 130 软件包,现在此代码不起作用

python - 关闭套接字服务器-Python

ios - 子 ViewControllers 数组在具有各种容器的 View Controller 中是否具有特定顺序?

configuration - elasticsearch 多个 nic 绑定(bind)网络接口(interface)

linux - 如何编译linux bridge?