我正在尝试通过wifi向C#tcpip服务器上的iphone / ipodtouch应用程序发送/接收数据。为此,我使用了谷歌项目中的cocoaAsyncSocket。如果我按下一个按钮,我从ipod发送请求到服务器它返回所请求的数据(例如歌曲标题)..我想知道每一首歌是什么歌...所以从C#服务器我发送间隔为1给我的应用的第二条消息。在我的应用程序中,间隔为1秒的计时器,我调用asyncSocket读取readDataWithTimeout方法。我的问题是,在8-9秒后,该方法不再被调用。与服务器的连接仍处于活动状态,C#服务器仍然发送数据..
我想做的是以下事情: - > winamp播放了一首歌 - > C#server询问winamp他正在播放什么歌曲并将歌曲标题发送到我的应用程序。 - > iPhone应用程序接收数据并显示它
我不知道为什么在短时间内不再调用readDataWithTimeout方法。也许是因为C#服务器发送的消息之间的时间很短?
谢谢你, 索林
答案 0 :(得分:2)
这里有几件事。首先,为什么每一秒都这样,而不仅仅是歌曲的变化?在iPhone电池上这将是非常昂贵的,以这种方式不断喋喋不休。即使在桌面上也没有理由这样做。
因此,如果我理解正确,iPhone会连接到.NET并要求提供歌曲。 .NET返回歌曲并使套接字保持打开状态。每一秒,.NET都会写入其套接字,而每秒钟都会从其套接字读取。
我怀疑发生的事情是,在某个时刻readDataWithTimeout:tag:
的超时在下一个NSTimer激发之前不会过期(两者都没有真正保证它何时会触发)。然后,您可能会同时运行两个readDataWithTimeout:tag:
调用,可能会使套接字委托感到困惑。
更好的解决方案是“长期调查”。在iPhone方面,以相当长的超时时间(例如30-60秒)呼叫readDataWithTimeout:tag:
。每次它返回时,只需循环回到它:
while (self.isRunning) {
[socket readDataWithTimeout:60 tag:0];
}
然后在-onSocketDidDisconnect:
和-onSocket:willDisconnectWithError:
中,确保将self.isRunning
设置为NO
。完全摆脱NSTimer。
答案 1 :(得分:1)
我让它工作......稍微阅读......所以当数据以未知的间隔到达AsyncSocket时,我使用了以下代码(我不知道它是否是最好的解决方案,但它适用于什么我想要):
- (void) readDataFromSocket
{
[socket readDataWithTimeout:-1 tag:0];
}
- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
NSData *strData = [data subdataWithRange:NSMakeRange(0, [data length])];
NSString *msg = [[[NSString alloc] initWithData:strData encoding:NSUTF8StringEncoding] autorelease];
if(msg)
{
if([msg isEqualToString:@"something"])
{
Do stuff
}
else
{
Do something else
}
}
}
else
{
NSLog(@"Error converting received data into UTF-8 String");
}
[socket readDataWithTimeout:-1 tag:0];
}
我在我的应用程序中调用一次调用套接字[socket readDataWithTimeout:-1 tag:0]方法的readDataFromSocket方法。它应该只在应用程序中调用一次,因为在方法 - (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag方法在最后一行我再次调用[socket readDataWithTimeout: -1标签:0];告诉套接字监听套接字。当数据到达时,套接字将读取它。
希望它有所帮助..