没有看到通过TCP
接收的所有数据,我想与我作为一个TCP客户端使用,但不知何故没有被在Wireshark中被显示的所有数据在我的代码可用套接字接收数据。没有看到通过TCP
随着Wireshark的我可以看到进入的数据包和测试工具(不是我做的),显示的数据我希望它的方式。
当我在下面的例子中输出recData
的长度时,它与WireShark中看到的数据的长度相关,所以一切看起来都很好。
然而,当我想显示所接收的消息作为一个可读的字符串(UTF-8编码的XML),但只能看到,我期望的消息的一部分。
的Socket
我使用:
private Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
private byte[] _recieveBuffer = new byte[1024];
public void Connect()
{
try
{
sock.Connect(new IPEndPoint(IPAddress.Parse(this.IpAddress), this.Port));
sock.ReceiveBufferSize = _recieveBuffer.Length;
}
catch (Exception ex)
{ }
sock.BeginReceive(_recieveBuffer, 0, _recieveBuffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), null);
}
private void ReceiveCallback(IAsyncResult ar)
{
int received = sock.EndReceive(ar);
if (received <= 0)
return;
byte[] recData = new byte[received];
Buffer.BlockCopy(_recieveBuffer, 0, recData, 0, received);
if (onDataReceived != null)
onDataReceived(this, new MyNewEventargs(recData));
Console.WriteLine(Encoding.UTF8.GetString(recData));
sock.BeginReceive(_recieveBuffer, 0, _recieveBuffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), null);
}
我注意到的是,所述第二接收包(图像中的一个高亮显示)是大约两倍大小第一包。
当我看包的内容,我可以看到,第一个包含1个完整的XML项目和第二个包含2
然而,当我打印第二包的内容为字符串我仍然只看到一个XML项目,所以第三个XML项目丢失了。
我希望完整的XML消息是这样的:
//First package
<?xml version="1.0" standalone="yes"?>
<Xml>
<Element1 Attirbute1="First item" Attirbute2="0" Attirbute3="0" Attirbute4="0" Attirbute5="0">
<Element2 Attirbute1="600" Attirbute2="1" Attirbute3="bla"/>
</Element1>
</Xml>
//First item of second package
<?xml version="1.0" standalone="yes"?>
<Xml>
<Element1 Attirbute1="Second item" Attirbute2="0" Attirbute3="0" Attirbute4="0" Attirbute5="0">
<Element2 Attirbute1="600" Attirbute2="1" Attirbute3="bla"/>
</Element1>
</Xml>
正如你可以看到第三个XML物品丢失:
<?xml version="1.0" standalone="yes"?>
<Xml>
<Element1 Attirbute1="First item" Attirbute2="0" Attirbute3="0" Attirbute4="0" Attirbute5="0">
<Element2 Attirbute1="600" Attirbute2="1" Attirbute3="bla"/>
</Element1>
</Xml>
<?xml version="1.0" standalone="yes"?>
<Xml>
<Element1 Attirbute1="Second item" Attirbute2="0" Attirbute3="0" Attirbute4="0" Attirbute5="0">
<Element2 Attirbute1="600" Attirbute2="1" Attirbute3="bla"/>
</Element1>
</Xml>
<?xml version="1.0" standalone="yes"?>
<Xml>
<Element1 Attirbute1="Third item" Attirbute2="0" Attirbute3="0" Attirbute4="0" Attirbute5="0">
<Element2 Attirbute1="600" Attirbute2="1" Attirbute3="bla"/>
</Element1>
</Xml>
该控制台显示看起来像这样的XML消息。
我想瞎搞与线程ANS秒表,看看它是否是一个时机的问题,但因为接收包的大小是正确的,我不认为这是我的问题的原因。
当我打印接收byte[]
到控制台,我没有做任何反序列化呢。
我怎样才能得到这个套接字接收(或让我看看)所有要发送的数据?
编辑:
一些更多的调试后,我看到了,我似乎得到所有的数据,但我觉得不顺心的事与Encoding.UTF8.GetString(recData)
。
第二时间ReceiveCallback
被调用时,将接收到的字节数是446,而不是221的数据被拷贝到字节[] recData
和它保持446个字节。当我在这条线上放置一个断点并手动将int received
更改为221(因此它只会将第一项复制到字节[])时,我得到的结果与它在446上时保持相同。
所以我确实得到所有的数据,但不知何故它不解码成我期望的字符串。
希望这是有道理的..
什么是你的“onDataReceived”在做什么?任何可能影响你逻辑的事情?
除了上面提到的事件处理程序之外,您的代码在这里无障碍地工作(至少使用通用HTML进行测试),接收并显示所有字节。
(注意:不可阻挡发表评论,that's为什么I'm发布回复随意删除。)
C.
目前,'OnDataReceived'仅对消息进行反序列化,并将其打印到文本框中。当我删除它时,我只得到第一个软件包,当我用'thread.sleep(50)'测试时,'我再次看到这两个软件包,如原始问题中所述。毕竟这是否是一个计时问题? – Rik
所以事件处理程序以某种方式改变了结果,也许数据本身很腥......也许你可以发布事件处理程序代码和接收到的两个数据包的原始字节? –
我认为这是在你的代码中的竞争条件,如果您在仍处于ReceiveCallback状态时收到数据,则不会再触发其他回拨。 – neuhaus
你可以显示发送方法吗? –
@neuhaus为什么? TCP套接字具有内部缓冲区。 –