iPhone/iPod 使用 CocoaAsyncSocket 从 C# tcpip 服务器接收消息
Posted
技术标签:
【中文标题】iPhone/iPod 使用 CocoaAsyncSocket 从 C# tcpip 服务器接收消息【英文标题】:iPhone/iPod receive messages from C# tcpip server using CocoaAsyncSocket 【发布时间】:2009-04-28 14:57:30 【问题描述】:我正在尝试通过 wifi 从 C# tcpip 服务器向 iphone/ipodtouch 应用程序发送/接收数据。为此,我使用了 google 项目中的 cocoaAsyncSocket。如果我按下一个按钮并从 ipod 向服务器发送一个请求,它会返回请求的数据(例如歌曲标题)..我想知道每一秒正在播放什么歌曲...所以从 C# 服务器我以 1 的间隔发送第二条消息到我的应用程序。在我的应用程序中,在间隔为 1 秒的计时器中,我调用了 asyncSocket 读取 readDataWithTimeout 方法。我的问题是 8-9 秒后不再调用该方法。与服务器的连接仍处于活动状态,C# 服务器仍在发送数据..
我想做的是以下事情: -> winamp 播放歌曲 -> C# 服务器询问 winamp 他正在播放什么歌曲并将歌曲标题发送到我的应用程序。 -> iphone 应用程序接收数据并显示它
我不知道为什么在很短的一段时间后不再调用 readDataWithTimeout 方法..可能是因为 C# 服务器发送消息之间的时间很短?
谢谢你, 索林
【问题讨论】:
【参考方案1】:这里有几件事。首先,为什么每秒钟都这样做,而不仅仅是歌曲变化?以这种方式不断颤动的 iPhone 电池将非常昂贵。即使在桌面上也没有理由这样做。
所以,如果我理解正确,iPhone 会连接到 .NET 并请求歌曲。 .NET 返回歌曲并保持套接字打开。每一秒,.NET 都会写入它的套接字,而 iPhone 每隔一秒就会从它的套接字读取。
我怀疑正在发生的事情是,在某些时候readDataWithTimeout:tag:
的超时不会在下一个 NSTimer 触发之前到期(对于它何时触发都没有任何真正的保证)。然后,您可能会同时运行两个 readDataWithTimeout:tag:
调用,这可能会使套接字委托感到困惑。
更好的解决方案是“长期投票”。在 iPhone 端,调用 readDataWithTimeout:tag:
并有相当长的超时时间(比如 30-60 秒)。每次返回时,直接循环返回即可:
while (self.isRunning)
[socket readDataWithTimeout:60 tag:0];
然后在-onSocketDidDisconnect:
和-onSocket:willDisconnectWithError:
中,确保将self.isRunning
设置为NO
。完全摆脱 NSTimer。
不过,在 Winamp 真正改变歌曲之前,我仍然不会从 .NET 方面发布任何内容。一遍又一遍地发送相同的数据没有任何好处。
【讨论】:
你好抢劫,谢谢你的回答。我想到了这一点,因为例如,如果我以 30 秒的超时时间从套接字读取数据,如果 winamp 在该超时时间内更改一首歌曲,我的 ipod 应用程序将延迟(最多 30 秒)接收该数据,所以它不会被更新的数据......我怎么能以这样的方式进行从 ipod 到服务器的发送/读取过程,这样我就不会再犯我犯的第一个错误?谢谢你,索林 更准确地说..在我的应用程序中,我遇到了 C# 服务器必须将数据推送到应用程序的情况(例如,应用程序没有通过按下按钮明确请求的数据) 调用-readDataWithTimeout:tag:
将阻塞“超时”秒以等待数据。如果数据在那之前出现,它会立即发布-onSocketDidReadData:withTag:
,所以应该不会有延迟。【参考方案2】:
我让它工作了..再读了一点......所以当它以未知的时间间隔通过 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];
我在我的应用程序中调用了一次 readDataFromSocket 方法,该方法调用了套接字 [socket readDataWithTimeout:-1 tag:0] 方法。它应该只在应用程序中调用一次,因为在最后一行的方法 - (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag 方法中我再次调用 [socket readDataWithTimeout: -1 标记:0];它告诉套接字监听套接字。当数据到达时,套接字会读取它。
希望对某人有所帮助..
【讨论】:
以上是关于iPhone/iPod 使用 CocoaAsyncSocket 从 C# tcpip 服务器接收消息的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 AVAssetExportSession 覆盖 iPhone/iPod 库中的歌曲?
JavaScript 使用javascript检测iPad / iPhone / iPod
iPhone/iPod 使用 CocoaAsyncSocket 从 C# tcpip 服务器接收消息
关闭 iPhone/iPod 音乐后玩家返回游戏时游戏音乐不恢复