.NET Sockets Buffer Overflow No Error
I have one thread that is receiving data over a socket like this:
while (sock.Connected)
{
// Receive Data (Block if no data)
recvn = sock.Receive(recvb, 0, rlen, SocketFlags.None, out serr);
if (recvn <= 0 || sock == null || !sock.Connected)
{
OnError("Error In Receive, recvn <= 0 || sock == null || !sock.Connected");
return;
}
else if (serr != SocketError.Success)
{
OnError("Error In Receive, serr = " + serr);
return;
}
// Copy Data Into Tokenizer
tknz.Read(recvb, recvn);
// Parse Data
while (tknz.MoveToNext())
{
try
{
ParseMessageAndRaiseEvents(tknz.Buffer(), tknz.Length);
}
catch (System.Exception ex)
{
string BadMessage = ByteArrayToStringClean(tknz.Buffer(), tknz.Length);
string msg = string.Format("Exception in MDWrapper Parsing Message,
Ex = {0}, Msg = {1}", ex.Message, BadMessage);
OnError(msg);
}
}
}
And I kept seeing occasional errors in my parsing function indicating that the message wasn't valid. At first, I thought that my tokenizer class was broken. But after logging all the incoming bytes to the tokenizer, it turns out that the raw bytes in recvb weren't a vali开发者_开发技巧d message. I didn't think that corrupted data like this was possible with a tcp data stream.
I figured it had to be some type of buffer overflow so I set
sock.ReceiveBufferSize = 1024 * 1024 * 8;
and the parsing error never, ever occurs in testing (it happens often enough to replicate if I don't change the ReceiveBufferSize).
But my question is: why wasn't I seeing an exception or an error state or something if the socket's internal buffer was overflowing before I changed this buffer size?
I assume your tokenizer expects text (Utf8 ?) but (socket-)streams work with byte data. It is possible that a multibyte character is split in transport. A small buffer increases the likelihood of that happening.
If you are using ASCII you're safe, otherwise the solution would lay in using a TextReader as in-between.
I would also suggest confirming that the sender of the data is checking the number of bytes successfully written, and not assuming that all bytes were written successfully.
This is a common mistake when using Socket.Send, and may explain why you see the problem going away when you up the buffer size.
It is the sender's responsibility to retry until all bytes have been successfully written.
精彩评论