我必须通过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
}
}
}
答案 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终止似乎是可疑的。