套接字与特殊消息终止符异步读取数据

时间:2009-03-09 20:33:02

标签: c# sockets asynchronous

我必须通过tcp连接到服务器,该服务器使用0x4而不是标准0x0来终止响应。我想保持简单,并使用套接字类的同步发送/接收。发送有效但接收块无限期,因为服务器不会终止带有0x0的消息。我无法同步读取第一个0x4并关闭,因为我需要保持连接打开以发送更多消息。如果我可以使用BeginReceive在单独的线程上读取数据,那将会很棒,但看起来它仍然需要0x0终止符。我尝试将大小为1的缓冲区传递给BeginRecieve,希望它会为每个char读取调用我的委托,但它似乎不会那样工作。它读取第一个字符并停止。

任何想法?

这是应用

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;


namespace SocketTest
{
    public partial class SocketTestForm : Form
    {
        Socket socket;
        byte[] oneChar = new byte[1];

        public SocketTestForm()
        {
            InitializeComponent();
        }

        private void GetButton_Click(object sender, EventArgs e)
        {
            //connect to google
            IPHostEntry host = Dns.GetHostEntry("google.com");
            IPEndPoint ipe = new IPEndPoint(host.AddressList[0], 80);
            socket = new Socket(ipe.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
            socket.Connect(ipe);
            if( socket.Connected )
                Console.WriteLine("Connected");

            //write an http get header

            String request = "GET / HTTP/1.1\r\nHost: google.com\r\nConnection: Close\r\n\r\n";

            socket.Send(Encoding.ASCII.GetBytes(request));

            //read the response syncronously, the easy way...
            //but this does not work if the server does not return the 0 byte...

            //byte[] response = new byte[5000];
            //socket.Receive(response, response.Length, SocketFlags.None);
            //string res = Encoding.ASCII.GetString(response);
            //Console.WriteLine(res);

            //read the response async
            AsyncCallback onreceive = ByteReceived;
            socket.BeginReceive(oneChar, 0, 1, SocketFlags.None, onreceive, null);
        }

        public void ByteReceived(IAsyncResult ar)
        {
            string res = Encoding.ASCII.GetString(oneChar);
            if (res[0] == 0x4) ; //fire some event 
        }
    }
}

1 个答案:

答案 0 :(得分:2)

使用0x04的终止看起来很可疑,但是你的代码在一个字节后停止的原因是你只需要一个字节。如果你想要第二个字节,你必须再次询问。

如下所示更改ByteReceived应该可以获得所有字节,直到达到0x04:

public void ByteReceived(IAsyncResult ar)
{
    string res = Encoding.ASCII.GetString(oneChar);
    if (res[0] == 0x4)
    {
       //fire some event 
    }
    else
    {
       AsyncCallback onreceive = ByteReceived;
       socket.BeginReceive(oneChar, 0, 1, SocketFlags.None, onreceive, null);
    }
}

读取http响应的典型方法是读取字节,直到您点击标头的终结符,然后使用http标头中的内容长度字段来确定您还有多少字节需要读取。

同样,0x04终止似乎是可疑的。