TcpClient或HttpWebRequest到AppleTV在30秒后结束?我正在使用C#创建一个库,以使用Airplay协议将照片和视频发送到AppleTV(特别是第3代,但希望这无关紧要)。https://airlib.codeplex.com/根据这个规范,Airplay的所有命令都是HTTP端口70:http://nto.github.com/AirPlay.html我已经成功播放了照片和视频,但不管怎样我知道,AppleTV只能播放30秒的视频。看起来我发出播放命令的C#客户端在30秒时断开连接,这导致AppleTV结束播放会话。为什么我这么想:我很确定客户端请求需要在视频的“回放”期间保持连接,据我所知,我已经对其进行了编码。我真的无计可施了。我已经尝试了所有我能想到的方法,包括将请求作为HttpWebRequest和原始TcpClient(两者都有效但超时),将接收/发送超时设置为疯狂的数字,并循环遍历Tcp流以确保有“活动”。AppleTV似乎希望我发送一条“嘿,继续播放”消息,但我还没有从任何在线来源看到类似的消息。我希望这只是一些愚蠢的事情,而不是因为我缺乏Http/Tcp知识。这是我的代码:Uriurl="http://somevideo.com/video.mov";浮动开始位置=0;TcpClienttcpClient=newTcpClient("192.168.1.20",7000);tcpClient.ReceiveTimeout=100000;tcpClient.SendTimeout=100000;//获取要从中读取数据的客户端流。NetworkStreamclientStream=tcpClient.GetStream();stringbody="Content-Location:"+url+"n"+"Start-Position:"+startPosition+"n";stringrequest="POST/playHTTP/1.1n"+"User-Agent:MediaControl/1.0n"+"Content-Type:text/parametersn"+"Content-Length:"+Encoding.ASCII.GetBytes(body)。长度+"n"+"X-Apple-Session-ID:"+_sessionGuid.ToString()+"nn";sendMessage(clientStream,请求);sendMessage(clientStream,body);byte[]myReadBuffer=newbyte[1024];StringBuildermyCompleteMessage=newStringBuilder();intnumberOfBytesRead=0;//传入消息可能比缓冲区大do{try{numberOfBytesRead=clientStream.Read(myReadBuffer,0,myReadBuffer.Length);我的完成eMessage.Append(Encoding.ASCII.GetString(myReadBuffer,0,numberOfBytesRead));Thread.Sleep(10);//让iOS设备赶上发送数据}catch(System.IO.IOException){}}while(tcpClient.Connected);//在检查可用数据之前检查它是否已连接,因为程序可能会退出并且套接字在读取中途关闭注意:使用telnet我可以通过端口7000连接到AppleTV并粘贴此命令以播放整个视频:POST/播放HTTP/1.1用户代理:MediaControl/1.0内容类型:文本/参数内容长度:89X-Apple-Session-ID:fb6d816a-a5ad-4e8f-8830-9642b6e6eb35内容位置:http://192.168.1.11:82/2012/2012_03_11/IMG_1328.MOVStart-Position:0我在端口82上运行CassiniWeb服务器,但这也适用于IIS这进一步证明.Net堆栈在30秒内完成了它导致断开连接的原因。终于,我明白了。终止连接的不是.Net代码,而是AppleTV本身。使用wireshark,我能够看到来自AppleTV的正确Ack和Fin消息,30秒后我没有在该连接上收到任何新消息。为了解决这个问题,我通过玩弄Telnet发现AppleTV似乎并不关心你发送什么,只要你定期发送一些东西,这似乎就可以保持连接。使用HttpWebRequest,发送/接收部分非常精确。它是为标准的Http请求和响应而设计的,如果您需要做任何其他事情,您只需启动一个新的HttpWebRequest而不是使用现有的。尝试在同一HttpWebRequest错误上发送第二条消息。所以只好用TcpClient,最后还得重做。//////开始播放视频。//////要播放的视频的URL。///视频的起始位置。此值必须介于0和1之间publicvoidStartVideo(Uriurl,floatstartPosition=0){if(startPosition>1){thrownewArgumentException("起始位置必须介于0和1");}TcpClienttcpClient=newTcpClient("192.168.1.20",7000);tcpClient.ReceiveTimeout=100000;tcpClient.SendTimeout=100000;//获取要从中读取数据的客户端流。NetworkStreamclientStream=tcpClient.GetStream();stringbody="Content-Location:"+url+"n"+"Start-Position:"+startPosition+"n";stringrequest="POST/playHTTP/1.1n"+"User-Agent:MediaControl/1.0n"+"Content-Type:text/parametersn"+"Content-Length:"+Encoding.ASCII.GetBytes(body)。长度+"n"+"X-Apple-Session-ID:"+_sessionGuid.ToString()+"nn";//发送消息头sendMessage(clientStream,request);//发送正文sendMessage(clientStream,body);//获取响应nsebyte[]myReadBuffer=newbyte[1024];StringBuildermyCompleteMessage=newStringBuilder();intnumberOfBytesRead=0;numberOfBytesRead=clientStream.Read(myReadBuffer,0,myReadBuffer.Length);myCompleteMessage.Append(Encoding.ASCII.GetString(myReadBuffer,0,numberOfBytesRead));//现在开始执行“keepalive”while(true){//简单地每两秒发送一次字符“ok”sendMessage(clientStream,"ok");线程.睡眠(2000);}}//////通过NetworkStream发送消息//////向下发送消息的流///要发送的消息publicvoidsendMessage(NetworkStreamclientStream,stringmessage){byte[]buffer=新的ASCIIEncoding().GetBytes(消息);尝试{clientStream.Write(buffer,0,buffer.Length);clientStream.Flush();}catch(System.IO.IOExceptione){Debug.WriteLine("IOException:"+e.Message);显然这不是最终答案,但它是让它工作的最低限度如果有人知道实际的Apple硬件发送的是什么而不是“确定”,请添加注释。以上是C#学习教程:TcpClientorHttpWebRequestendsafter30secondstoAppleTV?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
