GCDAsyncSocket - не получает данные - AsyncSocket работает нормально - PullRequest
6 голосов
/ 01 июля 2011

Я подключил клиент iPhone к серверу с помощью GCDAsyncSocket. Сервер работает .Net на сервере Windows. Соединение в порядке, и оно также хорошо передает данные.

Затем я приказываю клиенту войти в прием сразу после отправки ...

[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]

Есть идеи, что я сделал не так?

Для этого я поместил сообщение в коде изумленных взглядов, но никаких действий нет, поэтому не уверен, получу ли я ответ или нет.

В идеале, если у кого-то есть пример кода, который получает, это будет здорово! спасибо!

Ответы [ 6 ]

9 голосов
/ 02 декабря 2011

Возможно, что-то не так с орфографией.(Это случилось со мной, и я искал часы, пока не увидел небольшую разницу)

GCDAsyncSocket переименовал все обратные вызовы делегатов из onSocket в сокет , чтобы соответствоватьСтиль именования яблок.

В приведенном выше примере вы упомянули

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

переименуйте его в

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

Это должно решить эту проблему.

И в моем коде у меня тоже была другая проблема.Убедитесь, что объект, который вызывает GCDAsyncSocket, все еще жив, пока вы подключаетесь.GCDAsyncSockets делегат является слабой ссылкой на ваш объект.А поскольку он асинхронный, делегат может стать равным нулю (автоматический выпуск или экземпляр был создан внутри метода, который уже оставлен), пока сокет отвечает.В результате он не вызывается, но класс, запустивший сокет, уже освобожден из памяти.Это особенно актуально, если вы используете ARC вместе с GCDAsyncSocket.

Надеюсь, это поможет

3 голосов
/ 14 октября 2013

У меня была такая же проблема, и я был готов сдаться. Моя проблема была на стороне сервера. В моем методе делегата 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 голосов
/ 01 июля 2011

Вы уверены, что ваш сервер отправляет данные, завершенные просто 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];
1 голос
/ 02 февраля 2012

Я думаю, что проблема исходит от того, что вы отправляете.Если содержимое содержит LF где-то в вашем файле, чтение закончится, когда оно прочитает LF.Вы должны кодировать base64 перед отправкой файла или читать до размера.

0 голосов
/ 10 ноября 2014

Добавить:
[sock readDataWithTimeout: -1 tag: 0];

в конце didConnectToHost.

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

    [sock readDataWithTimeout:-1 tag:0];
}
0 голосов
/ 04 января 2012

Я разработал почти тот же код, сторона сервера ios сторона клиента vb net.С vb.net я отправляю файл размером 147 КБ с помощью метода 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];
}

У меня нет проблем с подключением и началом отправки / получения, ноМоя единственная проблема в том, что я получаю 152 КБ, если я использую CRData, и 143 КБ, если я использую разделитель LFData.

Ответ заключается в следующем: как добавить разделитель в vb net при отправке файла?

...