套接字c#不完整的标头

时间:2013-05-23 14:31:02

标签: c# sockets http shoutcast

您好我已经尝试向Shoutcast流网站发送和http请求,然后阅读响应, 我有两个来源,一个是主要的(我用wpf测试过),其他的有点 套接字的帮手...好吧所有的工作,与localhost和其他网站 但是当我尝试向“209.9.238.6:6042”发送请求时,响应中的标题永远不会 完成但是中继。

我已经做了很多测试,但它只适用于Thread.sleep(200); 发送和接收之间看(1),所以看来listen()来得太早了 只下载了一部分......

你能帮助我吗?

main.cs

 public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void connectionButton_Click(object sender, RoutedEventArgs e)
        {
            var url = "209.9.238.6:6042";

            var sockHelp = new SocketHelper(url);

            sockHelp.onConnect += sockHelp_onConnect;
            sockHelp.connect();

        }

        void testDebug(string str) {

            Action action = () => debugTxt.Text = str;
            Dispatcher.BeginInvoke(action);

        }

        void sockHelp_onConnect(object sender, SocketHelperEventArgs e)
        {

            var sockHelp = sender as SocketHelper;

            testDebug("Connected");

            var header = "";
            header+="GET / HTTP/1.0\r\n";
            header+="Accept: */*\r\n";
            header+="Host: 209.9.238.6\r\n";
            header+="Connection: close\r\n\r\n";

            sockHelp.onSend += sockHelp_onSend;
            sockHelp.sendAsync(Encoding.UTF8.GetBytes(header));

        }

        private void sockHelp_onSend(object sender, SocketAsyncEventArgs e)
        {
            var sockHelp = sender as SocketHelper;
            sockHelp.onReceive+=sockHelp_onReceive;

        //Thread.Sleep(200); (1)  uncomment this line... to make works

            sockHelp.listen();
        }

        void sockHelp_onReceive(object sender, SocketAsyncEventArgs arg_)
        {
            testDebug("Receiving");


            var t = Encoding.UTF8.GetString(arg_.Buffer);
            var idx = IndexOf(arg_.Buffer, new byte[] { 0x0d, 0x0a, 0x0d, 0x0a });

            if (idx < 0)
            {
                testDebug(Encoding.UTF8.GetString(arg_.Buffer));
                return ;
            }
            byte[] binBuff = new byte[idx + 1]; 
            System.Buffer.BlockCopy(arg_.Buffer, 0, binBuff, 0, idx + 1);
            testDebug(Encoding.UTF8.GetString(binBuff));
        }

        private int IndexOf(byte[] searchIn, byte[] searchFor)
        {
            if ((searchIn != null) && (searchIn != null))
            {
                if (searchFor.Length > searchIn.Length) return 0;
                for (int i = 0; i < searchIn.Length; i++)
                {
                    int startIndex = i;
                    bool match = true;
                    for (int j = 0; j < searchFor.Length; j++)
                    {
                        if (searchIn[startIndex] != searchFor[j])
                        {
                            match = false;
                            break;
                        }
                        else if (startIndex < searchIn.Length)
                        {
                            startIndex++;
                        }

                    }
                    if (match)
                        return startIndex - searchFor.Length;
                }
            }
            return -1;
        }

    }


}

helper.cs

namespace TestSocket
{
    /// <summary>

    /// </summary>
    public class SocketHelperEventArgs : EventArgs
    {

        public SocketHelperEventArgs(SocketError se)
        {
            socketError = se;
        }
        public SocketHelperEventArgs() { }
        SocketError socketError;
        SocketAsyncEventArgs args;
    }


    public class SocketHelper
    {
        byte[] _buffer = new byte[1024*2];
        SocketAsyncEventArgs _args = new SocketAsyncEventArgs();

        readonly Socket _socket;

        public event EventHandler<SocketHelperEventArgs> onError;
        public event EventHandler<SocketHelperEventArgs> onConnect;

        public event EventHandler<SocketAsyncEventArgs> onReceive;
        public event EventHandler<SocketAsyncEventArgs> onSend;

        public SocketHelper(string url)
        {

            int port=0;
            string[] addressVector = url.Split(':');
            if (addressVector.Length == 1)
                port = 80;
            else
                port = int.Parse(addressVector[1]);

            _args.RemoteEndPoint = new DnsEndPoint(addressVector[0], port); ;

            _args.Completed += SocketAsyncEventArgs_Completed;


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


        }


        public void listen()
        {
            _args.SetBuffer(_buffer, 0, _buffer.Length);     

            _socket.ReceiveAsync(_args);
        }


        public void connect()
        {

            bool completesAsynchronously = _socket.ConnectAsync(_args);

            if (!completesAsynchronously)
            {
                SocketAsyncEventArgs_Completed(_args.ConnectSocket, _args);

            }
        }


        public void sendAsync(byte[] data) {

            _args.SetBuffer(data, 0, data.Length);
            _socket.SendAsync(_args);
        }

        private void SocketAsyncEventArgs_Completed(object sender, SocketAsyncEventArgs e)
        {

            // check for errors 
            if (e.SocketError != SocketError.Success)
            {

                if (onError != null) onError(this, new SocketHelperEventArgs(e.SocketError));

                CleanUp(e);
                return;
            }

            switch (e.LastOperation)
            {
                case SocketAsyncOperation.Connect:
                    if (onConnect != null) onConnect(this, EventArgs.Empty as SocketHelperEventArgs);
                    break;
                case SocketAsyncOperation.Send:
                    if (onSend!= null) onSend(this, e);
                    break;
                case SocketAsyncOperation.Receive:
                    if (onReceive != null) onReceive(this,e);
                    break;
            }
        }

        private void CleanUp(SocketAsyncEventArgs e)
        {
            if (e.ConnectSocket != null)
            {
                e.ConnectSocket.Shutdown(SocketShutdown.Both);
                e.ConnectSocket.Close();
            }
        }



    }
}

1 个答案:

答案 0 :(得分:2)

您似乎假设您将在一次阅读中获得整个回复。那不对。当数据可用时,您将从套接字获得一些数据。您需要根据应用程序级协议(HTTP或ICY或您正在使用的任何内容)检测是否有更多数据,如果是,请重新设置异步读取。

现在你正在消耗套接字接收缓冲区中发生的任何事情。等待似乎只是因为在超时后更多的数据堆积在那里,但是不能保证你得到了所有东西。