Jump to content
  • Advertisement
Sign in to follow this  
Promit

Lots of TCP data to localhost never arrives (C++, C#)

This topic is 3321 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm using boost::asio to send some strings to a localhost client. The server accepts the connection with a TCP socket, and then simply sends some strings like so: std::string message = ... + "\r\n"; boost::asio::write(m_socket, boost::asio::buffer(message)); That gets called quite a lot of times. I'm then receiving the data on the client via C#, in a relatively simple ReadLine loop:
public string Receive()
{
	try
	{
		if(m_stream == null)
			return string.Empty;

		StreamReader reader = new StreamReader(m_stream, Encoding.ASCII);
		string result = reader.ReadLine();
		return result;
	}
	catch(Exception)
	{
		return null;
	}
}





I have a thread that calls that function continuously until it returns null. Lazy, but it works. Almost. A snip of the expected output (this is the server's record of what it's sending):
System.Windows.Forms.ButtonInternal.ButtonStandardAdapter.PaintThemedButtonBackground : call count = 1
System.Windows.Forms.ButtonInternal.ButtonStandardAdapter.PaintWorker : call count = 1
System.Windows.Forms.ButtonInternal.ButtonStandardAdapter.PaintLayout : call count = 1
System.Windows.Forms.ButtonInternal.ButtonBaseAdapter.Paint : call count = 1
System.Windows.Forms.ButtonInternal.ButtonBaseAdapter.CreateTextFormatFlags : call count = 2
System.Windows.Forms.ButtonInternal.ButtonBaseAdapter.DrawFocus : call count = 1
System.Windows.Forms.ButtonInternal.ButtonBaseAdapter.DrawImage : call count = 1
System.Windows.Forms.ButtonInternal.ButtonBaseAdapter.DrawText : call count = 1
System.Windows.Forms.ButtonInternal.ButtonBaseAdapter.PaintField : call count = 1
System.Windows.Forms.ButtonInternal.ButtonBaseAdapter.CommonRender : call count = 1
System.Windows.Forms.ButtonInternal.ButtonBaseAdapter..cctor : call count = 1
ColorOptions.Adjust255 : call count = 6
ColorOptions.Calculate : call count = 1
System.Windows.Forms.Button.CreateStandardAdapter : call count = 1




And the actual received of the same snip:
r.PaintThemedButtonBackground : call count = 1
CreateStandardAdapter : call count = 1



As you can see, I'm missing a few lines. I suck at networks, and I thought TCP was supposed to prevent this sort of thing happening. What did I screw up here?

Share this post


Link to post
Share on other sites
Advertisement
Is it just hanging, waiting for more data to be recieved? Or is it actually returning null? If it is returning null, is it because ReadLine returns null or an exception is thrown?

I'm sure you've already checked all these things, but what did you find? :-P

Share this post


Link to post
Share on other sites
Quote:
StreamReader reader = new StreamReader(m_stream, Encoding.ASCII);
string result = reader.ReadLine();
return result;


Shouldn't reader be created once for duration of the stream (if m_stream is supposed to be NetworkStream).

Do you check the ::write() return value? How large are individual strings?

Share this post


Link to post
Share on other sites
Quote:
Original post by Antheus
Quote:
StreamReader reader = new StreamReader(m_stream, Encoding.ASCII);
string result = reader.ReadLine();
return result;


Shouldn't reader be created once for duration of the stream (if m_stream is supposed to be NetworkStream).
Yeah, the reader will do internal buffering, if I'm not mistaken, so if you create a new one each time, you'll miss data that the old one has buffered.

I'm not sure though, because you say you receive data in a "ReadLine loop" but there's no loop there :-)

Edit: Oh, wait, I missed where you say "I have a thread that calls that function continuously until it returns null". Yeah, that's definitely the problem. With only a few packets, there won't be any additional data for the StreamReader to buffer, so it'll look like it works. But if you're sending a lot of data, the StreamReader will read past the end of the line and buffer up the results.

Share this post


Link to post
Share on other sites
Huh, I did not know that. Pick up new info all the time, I suppose. Anyway, I cached the StreamReader and everything works beautifully.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!