GCDAsyncSocket - 不接收数据 - AsyncSocket工作正常

时间:2011-07-01 13:17:43

标签: iphone objective-c sockets asyncsocket

我使用GCDAsyncSocket将iPhone客户端连接到服务器。服务器在Windows服务器上运行.Net。连接良好,也可以很好地发送数据。

然后我告诉客户在发送后直接接收...

[sock readDataToData:[GCDAsyncSocket LFData] withTimeout:15 tag:1]; 

我也有这个设置接收:

- (void)onSocket:(GCDAsyncSocket *)sock didReadData:(NSData *)data 
withTag:(long)tag 

还有:

   - (NSTimeInterval)socket:(GCDAsyncSocket *)sock shouldTimeoutReadWithTag:(long)tag 

如果我等待超时,则调用超时方法。

如果我从服务器发送数据,则不会调用超时,所以我假设 客户看到了什么,但没有迹象表明 客户方。

我还补充说:

- (void)socket:(GCDAsyncSocket *)sock didReadPartialDataOfLength: (NSUInteger)partialLength tag:(long)tag 

希望我能看到一个部分数据包,但这不会被触发 无论是。

如上所述,如果发送,超时不会触发 从服务器到客户端的东西。不过我会想到的 如果它没有收到终结符,它也会超时 字符。我也试过读长度为3但没有 有所作为。

GCDAsyncSocket就是问题所在。 AsyncSocket似乎工作正常。

也许它的init错了?

dispatch_queue_t mainQueue = dispatch_get_main_queue();

asyncSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:mainQueue]

任何想法我做错了什么?

我在护目镜代码上贴了一个帖子,但没有任何活动,所以不确定我是否会得到答案。

理想情况下,如果有人有一个示例代码,接收器工作将是伟大的!谢谢!

6 个答案:

答案 0 :(得分:9)

拼写可能有问题。 (所以这发生在我身上,我正在寻找几个小时,直到我看到了微小的差异)

GCDAsyncSocket将所有委托回调从 onSocket 重命名为套接字,以匹配Apples命名样式。

在上面的示例中,您提到了

- (void)onSocket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag 

将其重命名为

- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag 

这可以解决这个问题。

在我的代码中,我也遇到了另一个问题。 在连接时,确保调用GCDAsyncSocket的对象仍处于活动状态。 GCDAsyncSockets委托是对象的弱引用。并且因为它是异步的,所以当套接字响应时,委托可以变为零(自动释放,或者实例是在已经离开的方法中创建的)。结果它似乎没有被调用,但启动套接字的类已经从内存中释放。如果您将ARC与GCDAsyncSocket一起使用,则会发生这种情况。

希望这有帮助

答案 1 :(得分:3)

我有同样的问题,并准备放弃。我的问题是服务器端。在我的委托方法onSocket:didAcceptNewSocket:我在错误的套接字上调用了一个读取。这解决了它。

-(void)onSocket:(AsyncSocket *)sock didAcceptNewSocket:(AsyncSocket *)newSocket
{
    NSLog(@"Connection Socket connected to ipad at %@",[newSocket connectedHost]);
    _ipadSocket = newSocket;
    [_ipadSocket setDelegate:self];

    //***This code was the faulty line. I was calling listen on sock not newSocket
    [_ipadSocket readDataToData:[AsyncSocket CRLFData] withTimeout:10 tag:0];
}

答案 2 :(得分:2)

您确定您的服务器发送的数据仅以LineFeed而不是CRLF终止吗?或者您从服务器发回的数据可能没有任何终止? readDataToData将一直等到收到数据中的终止字符。

这是我用来连接的代码。我已经删除了我认为不必要的内容 - 希望我没有删除任何重要内容。

Init socket

asyncSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];

连接

[asyncSocket connectToAddress:addr error:&err]

连接时

- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port {
    connected = YES;

发送(不超时)

[asyncSocket writeData:dataData withTimeout:-1 tag:0];

请求阅读数据

[asyncSocket readDataToData:[GCDAsyncSocket CRLFData] withTimeout:30.0 tag:0];

数据已经通过(我只是发送字符串)

- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {
    NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

答案 3 :(得分:1)

我认为问题来自你发送的内容。 如果内容在文件中的某处包含LF,则读取将在读取LF时结束。 您应该在发送文件之前进行base64编码,或者读取直到大小。

答案 4 :(得分:0)

我开发了几乎相同的代码,侧服务器ios端客户端vb net。 从vb.net我发送一个147 kb的文件与metod socket.sendfile,而在ios中使用AsyncSocket所以:

- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag;
{

        [sock readDataToData:[AsyncSocket CRData] withTimeout:-1 tag:0]; 

        [dataFile appendData:data];
}

我没有连接和启动发送/接收没有任何问题,但我唯一的问题是,如果我使用CRData,我会收到152 kb,如果我使用LFData分隔符,则收到143 kb。

答案是如何在发送文件时在vb net中添加分隔符?

答案 5 :(得分:0)

添加:
[sock readDataWithTimeout:-1 tag:0];

在didConnectToHost的末尾。

- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port
{
    //Your Code

    [sock readDataWithTimeout:-1 tag:0];
}