您的位置:首页 > 理论基础 > 计算机网络

http发送流数据问题,可能的原因和解决办法

2013-03-14 15:56 639 查看
http://hi.baidu.com/sunwater007/item/1438dc098af313803c42e290

此程序是目的是以http的方式循环的把一个流数据发送到media player.

为了调试这个socket问题,整整让我痛苦了四天.

正常情况下的socket的同步编程不是太难,我原以为这个小程序应该不会有问题,然而,我错了.

程序让我失望了,而且这种错误是不可跟踪的,而且出现是有概率的.更增加了调试难度.

试了N久,我突然在调试的时候不断的换port,发现每次第一次换port,media player都能正常的接收到所有的数据.然而,如果故意让media player故意发一个错误的http请求,那么接下来media player一般在接受到第一个Block的以后强迫关闭TCP连接.致使server出错.

我猜想可能media player是有缓冲的,如果第一次接受到数据,cache进去,下次再请求,它发现还是相同的block,可能就主动关闭tcp.因为在使用http封装的block里就没有指出content-length,这个普通的http是有些不一样.

而且media player在首次请求的时候会首先发自己的一个参数信息列表,但是不需要接受数据.所以需要给它一个204的响应代码.

所以为了避免这些问题,我在发送完成后就关闭掉BinaryReader,FileStream和passive socket,目前出现不能接受数据的概率大大减少.其实在实际应用当中是不应该关闭socket的.也不存在多次http请求的问题.

程序如下:

==============

protected void start_listen()

{

const int BLOCK_SIZE = 64 * 1024;

const string LOCAL_IP = "127.0.0.1";

const int IP_PORT = 21100;

int received_http_head_length = -1;

Socket server_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

IPEndPoint local_endpoint = new IPEndPoint(IPAddress.Parse(LOCAL_IP), IP_PORT);

server_socket.Bind(local_endpoint);

try

{

do

{

server_socket.Listen(10);

Socket passive_socket = server_socket.Accept();

Byte[] http_request_head = new byte[512 * 1024];

received_http_head_length = passive_socket.Receive(http_request_head);

if(received_http_head_length < 0)

{

break;

}

else

{

string request_http_head_string = Encoding.Default.GetString(http_request_head, 0, received_http_head_length);

string response_http_head_string = null;

if(request_http_head_string.IndexOf("Connection: Keep-Alive") != -1)

{

FileStream video_file_stream = new FileStream(@"e:\test.wmv", FileMode.Open, FileAccess.Read);

Byte[] video_file_stream_buffer = new byte[video_file_stream.Length];

BinaryReader bin_reader = new BinaryReader(video_file_stream);

bin_reader.Read(video_file_stream_buffer, 0, video_file_stream_buffer.Length);

response_http_head_string += "HTTP/1.1 200 OK\r\n";

response_http_head_string += "Content-Type: video/octet-stream\r\n";

response_http_head_string += "\r\n";

Byte[] response_http_head_buffer = Encoding.ASCII.GetBytes(response_http_head_string);

passive_socket.Send(response_http_head_buffer, 0, response_http_head_buffer.Length, SocketFlags.None);

for(int i = 0; i <= video_file_stream.Length / BLOCK_SIZE; i++)

{

if( i != video_file_stream.Length / BLOCK_SIZE)

{

passive_socket.Send(video_file_stream_buffer, i * BLOCK_SIZE, BLOCK_SIZE, SocketFlags.None);

}

else

{

passive_socket.Send(video_file_stream_buffer, i * BLOCK_SIZE, video_file_stream_buffer.Length - i * BLOCK_SIZE, SocketFlags.None);

}

}

passive_socket.Close();

bin_reader.Close();

video_file_stream.Close();

}

else

{

response_http_head_string += "HTTP/1.1 204 OK\r\n";

response_http_head_string += "\r\n";

Byte[] response_http_head_buffer = Encoding.ASCII.GetBytes(response_http_head_string);

passive_socket.Send(response_http_head_buffer, 0, response_http_head_buffer.Length, SocketFlags.None);

passive_socket.Close();

}

}

}while(true);

}

catch(Exception ex)

{

Console.Write(ex.Message);

}

}

private void listen_btn_Click(object sender, System.EventArgs e)

{

listen_btn.Enabled = false;

start_listen();

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐