我试图简单地使用GCDAsyncSocket发送和接收消息,但无法使其工作.
我正在成功建立连接并写入消息,但是当涉及到阅读时,我的委托从未被调用过.
我正在使用ios5和这个设置:
客户:
-(void) connectToHost:(HostAddress*)host{
    NSLog(@"Trying to connect to host %@", host.hostname);
    if (asyncSocket == nil)
    {
        asyncSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
        NSError *err = nil;
        if ([asyncSocket connectToHost:host.hostname onPort:host.port error:&err])
        {
            NSLog(@"Connected to %@", host.hostname);
            NSString *welcomMessage = @"Hello from the client\r\n";
            [asyncSocket writeData:[welcomMessage dataUsingEncoding:NSUTF8StringEncoding] withTimeout:-1 tag:1];
            [asyncSocket readDataWithTimeout:-1 tag:0];
        }else
            NSLog(@"%@", err);
    }
}
不调用Delegate didReadData方法
-(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{
    NSLog(@"MESSAGE: %@", [NSString stringWithUTF8String:[data bytes]]);
}
服务器
-(void)viewDidLoad{
    asyncSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
    connectedSockets …GCDAsyncSocket委托不在swift类中调用,但在UIViewController类中工作得很好.下面是我的自定义类代码,在这个类中,connect函数将启动套接字连接,它的委托将永远不会被调用.我在网上搜索,也在GCDAsyncSocket github repo上搜索但没有成功.
class RXSocket: NSObject,GCDAsyncSocketDelegate {
func connect() {
    let asyncSocket = GCDAsyncSocket(delegate: self, delegateQueue: dispatch_get_main_queue())
    do {
        try asyncSocket?.connectToHost("www.google.com", onPort: 80)
    } catch _ as NSError {
    }
}
//MARK:- ASyncSocket Delegate
func socket(sock: GCDAsyncSocket!, didConnectToHost host: String!, port: UInt16) {
    print("didConnectToHost")
}
func udpSocket(sock: GCDAsyncUdpSocket!, didReceiveData data: NSData!, fromAddress address: NSData!, withFilterContext filterContext: AnyObject!) {
    print("didReceiveData")
}
func socketDidDisconnect(sock: GCDAsyncSocket!, withError err: NSError!) {
    print("socketDidDisconnect")
}
}
并在我的视图控制器类
    let rxSocket = RXSocket()
    rxSocket.connect()
在我的基于TCP套接字的服务器上,我通过流发送数据包,其中数据包由指定数据包中字节数的标头组成,后跟该字节数.对于那些熟悉Erlang的人,我只是设置{packet,4}选项.在iOS方面,我的代码看起来像这样,假设我想弄清楚此消息的流的大小:
[asyncSocket readDataToLength:4 withTimeout:-1 tag:HEADER_TAG];
这工作正常,并调用以下委托方法回调:
onSocket:didReadData:withTag:
我认为下一个合乎逻辑的步骤是弄清楚流的大小,我这样做:
  UInt32 readLength;
  [data getBytes:&readLength length:4];
  readLength = ntohl(readLength);
在服务器端硬编码一个12字节的字符串之后,readLength确实在客户端读取了12,所以到目前为止一切都很好.我继续以下内容:
 [sock readDataToLength:readLength withTimeout:1 tag:MESSAGE_TAG];
此时虽然onSocket:didReadData:withTag:不再调用回调.而不是读取超时,可能是因为我没有正确处理读取,这个委托方法被调用:
- (NSTimeInterval)onSocket:(AsyncSocket *)sock shouldTimeoutReadWithTag:(long)tag elapsed:(NSTimeInterval)elapsed bytesDone:(NSUInteger)length 
所以总的来说,服务器发送16个字节,一个4字节的头和一个12字节的二进制流.
我确信错误在于我如何使用CocoaAsyncSocket.在弄清楚它的大小之后,读取其余流的正确方法是什么?
**更新**
我改变了我的客户,现在似乎正在运作.问题是,我不明白readDataToLength与新解决方案的关系.这是我将我的初始阅读更改为:
[socket readDataWithTimeout:-1 tag:HEADER_TAG];
现在在我的回调中,我只是做以下事情:
- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {
    if (tag == HEADER_TAG) {
        UInt32 readLength;
        [data getBytes:&readLength length:4];
        readLength = ntohl(readLength);
        int offset = 4;
        NSRange range = NSMakeRange(offset, readLength);
        char buffer[readLength];
        [data getBytes:&buffer range:range];
        NSLog(@"buffer %s", buffer);
        //[sock readDataToLength:readLength withTimeout:1 tag:MESSAGE_TAG];
    } …我只是将所有CocoaAsyncSocket代码标记为非ARC代码,并且它给了我这3个错误:
Undefined symbols for architecture armv7:
  "_kCFStreamNetworkServiceTypeVoIP", referenced from:
      -[GCDAsyncSocket enableBackgroundingOnSocketWithCaveat:] in GCDAsyncSocket.o
  "_kCFStreamNetworkServiceType", referenced from:
      -[GCDAsyncSocket enableBackgroundingOnSocketWithCaveat:] in GCDAsyncSocket.o
  "_kCFStreamPropertySSLSettings", referenced from:
      -[GCDAsyncSocket maybeStartTLS] in GCDAsyncSocket.o
ld: symbol(s) not found for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)
有谁知道这意味着什么以及如何解决它?
我正在构建一个多播客户端,GCDAsyncUdpSocket而且我面临很多丢包.
我用Wireshark监控了服务器,并使用AirCap捕获了空中的WiFi数据包,我确信数据包是正确传输的.我还查看了GCDAsyncUdpSocket库中的调试跟踪,我发现有时socket4FDBytesAvailable:会使用大型参数调用,例如4000,但是当它读取套接字时,它会读取更少的字节 - 可能是500  - 这就是数据包丢失的地方.我增加了套接字缓冲区,但这没有帮助.
最后,我注意到使用Instruments的时间分析器,巧合与否,每次丢失数据包时都会创建一个新的DISPATCH_WORKER_THREAD实例.这是正常的吗?
debugging cocoa-touch grand-central-dispatch cocoaasyncsocket
我在处理读取超时的代码中查看了GCDAsyncSocket.m.如果我没有延长超时,似乎套接字已关闭,并且套接字没有选项保持.我不能使用无限超时(超时= -1),因为我仍然需要知道它何时超时,但也不希望它断开连接.我不确定这背后有什么原因.有人知道吗?
- (void)doReadTimeoutWithExtension:(NSTimeInterval)timeoutExtension
{
    if (currentRead)
    {
        if (timeoutExtension > 0.0)
        {
            currentRead->timeout += timeoutExtension;
            // Reschedule the timer
            dispatch_time_t tt = dispatch_time(DISPATCH_TIME_NOW, (timeoutExtension * NSEC_PER_SEC));
            dispatch_source_set_timer(readTimer, tt, DISPATCH_TIME_FOREVER, 0);
            // Unpause reads, and continue
            flags &= ~kReadsPaused;
            [self doReadData];
        }
        else
        {
            LogVerbose(@"ReadTimeout");
            [self closeWithError:[self readTimeoutError]];
        }
    }
}
仅供参考,https://github.com/robbiehanson/CocoaAsyncSocket/pull/126上有一个拉取请求,它添加了这个保持活动的功能,但尚未提取.
我正在努力尝试开发一种从iOS应用程序在我的本地网络上发现Logitech Harmony Hub设备的方法.这个概念的灵感来自于这个 NODE.JS项目,该项目似乎向该255.255.255.255地址发送了UDP广播,然后获得了Logitech的IP地址(这就是我所追求的).当我在Mac上测试家庭网络上的NODE.JS项目时,它成功找到了Logitech Harmony Hub.
我正在使用CocoaASyncSocket,并且必须承认,我对UDP广播/发现如何工作的理解可能在这里.这就是我正在做的事情;
import UIKit
import CocoaAsyncSocket
class ViewController: UIViewController, GCDAsyncUdpSocketDelegate {
var address = "255.255.255.255"
var port:UInt16 = 5224
var socket:GCDAsyncUdpSocket!
var socketReceive:GCDAsyncUdpSocket!
var error : NSError?
override func viewDidLoad() {
    super.viewDidLoad()
    let message = "_logitech-reverse-bonjour._tcp.local.\n61991".dataUsingEncoding(NSUTF8StringEncoding)
    socket = GCDAsyncUdpSocket(delegate: self, delegateQueue: dispatch_get_main_queue())
    socket.sendData(message, toHost: address, port: port, withTimeout: 1000, tag: 0)
    do {
        try socket.bindToPort(port)
    } catch {
        print(error)
    }
    do {
        try socket.enableBroadcast(true)
    } catch {
        print(error)
    }
    do …我正在使用CocoaAsyncSocket尝试创建TCP隧道/ mux/demux,通过端口对(A < - > B)转发所有连接.写入端口A的所有内容都应该从端口B"出来",反之亦然.我只能使用端口A和B,无法打开其他端口.
我正在创建2监听AsyncSocketsA和B,并有2个连接客户端阵列,并在
- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
   if (sock.localPort == B.localPort)
   {
       for (AsyncSocket * cl in clientsOfA)
       {
           [cl writeData:data withTimeout:-1 tag:0];
           [cl readDataWithTimeout:-1 tag:0];
       }
       [sock readDataWithTimeout:-1 tag:0];
   }
我在端口AI上读到的所有内容都将发送给端口B的所有客户端,反之亦然.在A的一侧有一个Safari,向A提出请求.
我的问题是:当数据从B端口返回时,在A端我有5个客户端(谢谢Safari ...),我不知道哪一个最初请求当前数据包,所以我发送数据到他们所有人......好吧......一切都搞砸了.
这种多路复用器/多路复用器能否以这种方式实现?或者实现这一目标的正确方法是什么?我怎样才能区分发起客户?
这发生在设备而不是模拟器上。我打开了我的应用程序,并使用GCDAsyncSocket连接到服务器。当我按下主页按钮,将应用程序置于后台,然后切换回该应用程序时,套接字仍会连接。没问题
但是,如果我实际上锁定了设备,然后立即将其解锁,则插座会断开连接。来自- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err {委托方法的错误说...
错误:错误域= GCDAsyncSocketErrorDomain代码= 7“套接字被远程对等方关闭” UserInfo = 0x20051cb0 {NSLocalizedDescription =套接字被远程对等方关闭}
我已经检查了服务器,没有代码明确破坏连接。我认为与iOS相关的事情会在应用程序发送到后台时终止连接。但是,然后,我想知道是否是因为该应用程序已发送到后台,那么为什么主页按钮不会终止连接,而锁定设备却可以呢?
有没有什么办法解决这一问题?
=====当前进度=====
似乎没有解决方案。现在作为解决方法。我只是重新连接,如果它意外断开连接。将使这个问题无法解决,以期创造奇迹。;)
我们已经使用 pod 来安装 Library。在一台计算机上运行良好。但是当我们将它推送到 Git 并克隆它时,它给了我这个错误:
ld:找不到 -lCocoaAsyncSocket clang 的库:错误:链接器命令失败,退出代码为 1(使用 -v 查看调用)
我们甚至使用 USB 复制了该项目。我们尝试了“pod install”。但这也行不通。我们都使用 XCode 7.3