【问题标题】:Not getting more messages after receiving first message from Java server in iOS client using NSInputStream使用 NSInputStream 从 iOS 客户端中的 Java 服务器接收到第一条消息后没有收到更多消息
【发布时间】:2014-12-23 12:20:02
【问题描述】:

我有一个 Java 服务器(它能够正确读取来自我的 iOS 客户端的请求——它甚至会生成一个响应并且似乎可以正确发送它,尽管我每次都收到来自服务器的第一条消息响应但没有收到收到第一条消息后的其他消息):

通信顺序

Step 1-> client send login message to server

Step 2-> server validate the user and sends login info to the clients

Step 3-> Message Packet1

         Message Packet2

         Message Packet3

         Message Packet4

 step-4-> I have checked server log and it says server has send 4 string 
          messages

 Step-5 -> On client side I am receiving only first message i.e. Message 
           Packet1, and there no other packets on NSInputStream showing. or NSStreamEventHasBytesAvailable option in delegate method->
- (void)stream:(NSStream *)theStream
handleEvent:(NSStreamEvent)streamEvent

大部分时间不调用不止一个,但有时它调用并获取 MessagePacket2 或 MessagePacket4 数据。

请帮帮我,我无法弄清楚为什么我只收到来自服务器的第一个数据包而不是 4 个数据包,因为服务器发送了 4 个数据包。

我使用了以下教程中的代码 -> http://www.raywenderlich.com/3932/networking-tutorial-for-ios-how-to-create-a-socket-based-iphone-app-and-server#comments

我的代码在这里->

@interface NetworkManager()<NSStreamDelegate>

@property (strong, nonatomic)NSInputStream        *objInputStream;
@property (strong, nonatomic)NSOutputStream       *objOutputStream;

@end

- (void)initializeNetworkCommunicationToServer
{
self.networkOpened = NO;

CFReadStreamRef readStream;
CFWriteStreamRef writeStream;

CFStreamCreatePairWithSocketToHost(NULL,
                                   (CFStringRef)SERVER_HOSTNAME,
                                   SERVER_PORT_ADDR,
                                   &readStream,
                                   &writeStream);

self.objInputStream = (__bridge_transfer NSInputStream *)readStream;
self.objOutputStream = (__bridge_transfer NSOutputStream*)writeStream;


[self.objInputStream setDelegate:self];
[self.objOutputStream setDelegate:self];

[self.objInputStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
                               forMode:NSDefaultRunLoopMode];
[self.objOutputStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
                                forMode:NSDefaultRunLoopMode];
[self.objInputStream open];
[self.objOutputStream open];

}

//------------------------------------------------------
pragma NSStreamDelegate delegate method
//------------------------------------------------------

- (void)stream:(NSStream *)theStream
handleEvent:(NSStreamEvent)streamEvent
{

switch (streamEvent)
{
    case NSStreamEventNone:
    {
        NSLog(@"NSStreamEventNone");
        break;
    }
    case NSStreamEventOpenCompleted:
    {
        NSLog(@"NSStreamEventOpenCompleted");

    }
        break;
    case NSStreamEventHasBytesAvailable:
    {
        NSLog(@"NSStreamEventHasBytesAvailable:");

        if (theStream == self.objInputStream)
        {
            while ([self.objInputStream hasBytesAvailable])
            {
                uint8_t buffer[1024];
                unsigned int len = 0;

                len = [self.objInputStream read:buffer
                                      maxLength:sizeof(buffer)];
                if (len > 0)
                {

                    NSString *output =
                    [[NSString alloc] initWithBytes:buffer
                                             length:len
                                           encoding:NSASCIIStringEncoding];

                    if (nil != output)
                    {
                        NSLog(@"server said: %@", output);
                    }

                }//end of if(len > 0)

            }//end of while
        } //end of  if (theStream == self.objInputStream)

    }
        break;
    case NSStreamEventErrorOccurred:
    {
        NSLog(@"NSStreamEventErrorOccurred: Can not connect to the host!");
    }
        break;
    case NSStreamEventEndEncountered:
    {

        NSLog(@"NSStreamEventEndEncountered & network connection ended");

        [theStream close];
        [theStream removeFromRunLoop:[NSRunLoop currentRunLoop]
                             forMode:NSDefaultRunLoopMode];

        theStream = nil;
    }
        break;

        // The NSStreamEventHasSpaceAvailable event indicates that you can write (at least one byte!) to the stream without blocking. That does not mean that previously written data is completely delivered to the other endpoint of the connection.
    case NSStreamEventHasSpaceAvailable:
    {
        NSLog(@"NSStreamEventHasSpaceAvailable");

        if(NO == self.networkOpened)
        {
            self.networkOpened = YES;

            [self sendMessage:@"login:username,password"];

        }
    }
        break;
    default:
    {
        NSLog(@"Unknown event");
    }
}
}


//------------------------------------------------------
#pragma mark - send packet
//------------------------------------------------------

- (void)sendMessage:(NSString*)lstrMessage
{
NSMutableData *data = [[NSMutableData alloc] initWithData:
                       [lstrMessage dataUsingEncoding:NSASCIIStringEncoding]];

unsigned char suffixBytes[] = {1, 1, 0};
[data appendBytes:suffixBytes length:3];

[self.objOutputStream write:[data bytes] maxLength:[data length]];

NSLog(@"message sent->%@",[NSString stringWithUTF8String:[data bytes]]);

}

【问题讨论】:

    标签: ios sockets client-server java-server nsinputstream


    【解决方案1】:

    我不知道您的代码有什么问题,但我在流调整方面的经验告诉我,尝试另一种使用 CF API 订阅 Core Foundation 流而不是免费桥接它到NS输入流。我的意思是 CFReadStreamSetClientCFReadStreamScheduleWithRunLoop 函数。您可以在 my helper class 中查看示例,以测试 POSInputStreamLibrary

    【讨论】:

      猜你喜欢
      • 2014-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-26
      • 2018-04-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多