7

我使用 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 似乎工作正常。

也许它的初始化是错误的?

dispatch_queue_t mainQueue = dispatch_get_main_queue();

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

任何想法我做错了什么?

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

理想情况下,如果有人有一个接收工作的示例代码,那就太好了!谢谢你!

4

6 回答 6

9

也许拼写有问题。(所以这发生在我身上,我一直在寻找几个小时,直到我看到了细微的差别)

GCDAsyncSocket 将所有委托回调从onSocket重命名为socket以匹配 Apple 的命名风格。

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

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

将其重命名为

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

这应该可以解决这个问题。

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

希望这可以帮助

于 2011-12-02T12:13:59.523 回答
3

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

这是我用来连接的代码。我已经去掉了我认为不必要的东西——希望我没有去掉任何重要的东西。

初始化套接字

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];
于 2011-07-01T14:31:58.297 回答
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];
}
于 2013-10-14T17:39:43.830 回答
1

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

于 2012-02-02T17:16:02.173 回答
1

添加 :

[sock readDataWithTimeout:-1 tag:0];

在 didConnectToHost 的末尾。

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

    [sock readDataWithTimeout:-1 tag:0];
}
于 2014-11-10T11:38:30.283 回答
0

我开发了几乎相同的代码,端服务器ios端客户端vb网。我从 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 中添加分隔符?

于 2012-01-04T15:29:46.520 回答