不完整的头与套接字c#

本文关键字:套接字 | 更新日期: 2023-09-27 18:14:57

嗨,我试着发送和http请求到一个广播流网站,然后读取响应,我有这两个源,一个是主要的(我用wpf测试过),另一个是小的套接字的助手…好吧,所有的工作,与localhost和其他网站但是当我尝试发送请求到"209.9.238.6:6042"时,响应的头永远不会完整但被截断。

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

你能帮我吗?

c

 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();
            }
        }

    }
}

不完整的头与套接字c#

您似乎认为您将在一次阅读中获得整个响应。这是不对的。当数据可用时,您将从套接字获得一些数据。您需要根据应用程序级协议(HTTP或ICY或您正在使用的任何协议)检测是否有更多的数据,如果有,则重新武装异步读取。

现在你正在消耗套接字接收缓冲区中发生的任何内容。等待似乎是有效的,因为在该超时之后会有更多的数据堆积在那里,但不能保证您将获得所有内容。