Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
134 views
in Technique[技术] by (71.8m points)

.net - Detect what data is (not yet) received by client on TCP stream in C#

I have a server that produces data, and the client receives this data. Only the server is too fast, and overloads the client. Eventually, the server will block on his send operations.

Now, I'm not really interested in old data from the server, rather, the server could skip a few messages and only send what's really important to the client.

On the client, I can use Client.Available to find out how much data is left in the stream, but I cannot figure out how to get this number on the server/sender. I can change the SendBufferSize, but rather I would know how much space is free in the SendBuffer and react to that accordantly.

I could let the client report how far he's lagging behind, but that feels like reinventing the TCP protocol at application level. Also, I do not trust a already slow client to warn my server in time.

Is there any way to read the TCP used/unused window size or send buffer?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

"Eventually, the server will block on his send operations"

Frankly, the above is the real bug here. There's no reason a server should block just because some client isn't receiving data fast enough. The server should be using non-blocking, asynchronous I/O and should otherwise continue to work normally, even if a client isn't reading fast enough.


Now, even if you address the blocking issue, you may also have the issue of the client receiving data not quickly enough. I.e. as you mentioned, you want the client to not receive data it can't process. You have at least a few choices here:

  • Require the client to actively response to a processed message before sending another one.

Pro: this is an immediate solution, in the sense that the server will never exceed the transmission rate that the client can handle.
Con: this would add bandwidth overhead and latency to your network protocol. A client with a high ping time will suffer, even if it's otherwise able to receive data quickly.

  • Keep track of the data rate the client appears to be able to handle, and slow the materialization of messages so that the server does not exceed this rate.

Pro: this solution will at all times maintain a transmission rate as high as the client is capable of dealing with.
Con: at least initially, and perhaps intermittently as the client's own capacity varies, this may exceed temporarily the client's ability to keep up

  • Use UDP, which will allow the network transport layer to discard datagrams that the client isn't processing quickly enough.

Pro: this solution delegates the whole problem to the network transport layer, leaving you to worry about the real details of your server and client
Con: UDP is inherently unreliable. In addition to dealing with dropped datagrams (which in your case is a benefit), you also must be prepared to handle datagrams received out of order, and individual datagrams received more than once.

That's about as specific an answer as is possible, given the broadly stated question.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...