我有一台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]]);
}
答案 0 :(得分:0)
我不知道你的代码有什么问题,但是我对流调优的经验告诉我,有一种方法可以尝试另一种方式来使用CF API订阅Core Foundation流,而不是免费将其桥接到NSInputStream。我的意思是CFReadStreamSetClient
和CFReadStreamScheduleWithRunLoop
函数。您可以在my helper class中查看如何执行此操作以测试POSInputStreamLibrary
。