.NET Forum / Languages / C# / July 2008
TcpClient read/write timeouts do not timeout
|
|
Thread rating:  |
Zytan - 21 Jul 2008 16:11 GMT I have a TcpClient. I set the read/write timeouts at 1 minute (in milliseconds). I get a NetworkStream from it and confirm the timeouts still exist. I do a NetworkStream.Write() and then a NetworkStream.Read(). Sometimes it sits and waits -- on the Write() or the Read() -- for 15 minutes before I get fed up and close the app.....
I am not connecting to a TcpListener. I am connecting to a Socket with ProtocolType.Tcp, which is acceptable. These read/writes normally work, but when I get 3 or 4 TcpClients all connecting at the same time, connection problems start. I don't understand why some of the connections fail. And, when they do fail, why don't the timeouts work?
I believe I have a bug in the server, but still, the timeouts should timeout.
Peter Duniho - 21 Jul 2008 16:49 GMT > [...] > I believe I have a bug in the server, but still, the timeouts should > timeout. Hard to say without seeing an actual concise-but-complete code example. That said, your description isn't all that clear either. Are you having read/write problems or connection problems? One paragraph says the former, while another says the latter.
Beware of using the TCP timeout: once the timeout occurs, the socket is no longer usable. Depending on your intent, you may be better off implementing timeout logic yourself elsewhere.
Pete
Zytan - 21 Jul 2008 18:10 GMT (It appears my reply isn't appearing, so I'll write again:)
> Hard to say without seeing an actual concise-but-complete code example. I use the code from this example: http://msdn.microsoft.com/en-us/library/system.net.sockets.tcpclient.aspx (except I implement timeouts.)
> Are you having > read/write problems or connection problems? It connects fine. The server sees the connection. The client gets stuck in the stream.Write() call, and the server never sees any data from it. (This occurs 1% o the time. The other 99%, everything works fine.)
> Beware of using the TCP timeout: once the timeout occurs, the socket is no > longer usable. Ok.
> Depending on your intent, you may be better off > implementing timeout logic yourself elsewhere. The implementation is: 1. connect, 2. send data, 3. get reply, 4. disconnect, so TcpClient seemed like the answer, since it was synchronous, just as I wanted it to be, to avoid the hassle of asynchronous code.
I even TURNED THE SERVER OFF once the stream.Write() got hung up, to see if that would end the stream.Write() call... and it doesn't. Write() should end because there's NO server and because the timeout is 1 minute, and it's been 20 minutes now. Even if my server code is a mess of bugs, this makes no sense.
Thanks, Pete,
Zytan
Zytan - 21 Jul 2008 17:59 GMT I just had the problem occur again, with NetworkStream.Write() doing its thing with a timeout... and it just sits and waits and waits and waits... it never times outs. So, I shut the server down just to see if THAT will make it at least end the function call and continue (since it's a synchronous call, so the program is delayed until it returns), and even THAT doesn't make the call end. It just sits and waits...
Even IF I have a bug in the server, once the server is not even online or running any more, there is absolutely no reason why this NetworkStream.Write() should not end and return. If it has a timeout of 1 minute, it should return after 1 minute no matter WHAT is happening.
> Hard to say without seeing an actual concise-but-complete code example. Indeed, but that is going to be nearly impossible to supply. Network code is just not precise. But, I can say that I'm using the source code from the TcpClient example on MSDN: http://msdn.microsoft.com/en-us/library/system.net.sockets.tcpclient.aspx EXCEPT that I implement a delay, and do proper exception handling.
> That said, your description isn't all that clear either. Are you having > read/write problems or connection problems? One paragraph says the > former, while another says the latter. Sorry, the connection IS established, otherwise an exception is thrown and it wouldn't even GET to the writing/reading stage (see TcpClient example on MSDN). The issue occurs on reading/writing. It just never returns from the function call Well, it works 99% of the time, but when it doesn't work, the call just doesn't end. The server sees the connection, but never receives any data from the client's Write() call.
> Beware of using the TCP timeout: once the timeout occurs, the socket is no > longer usable. Thanks for the tip. These are the kinds of things I'd like to know about.
> Depending on your intent, you may be better off > implementing timeout logic yourself elsewhere. All I desire is to connect to a server, give it some data, it processes it, and returns the data, and disconnects. A one shot deal. No repeats. This is why I chose TcpClient, I can: 1. connect, 2. write, 3. read, 4. disconnect, all synchronously, and save the headaches of writing Asynchronous code.
Zytan
Zytan - 21 Jul 2008 18:18 GMT I guess I've conclusively shown that either .NET is fried, or something else is causing this issue (i.e. me). And I think I may have found it.... so, hold up... before you waste your time reading my replies........
Zytan
Zytan - 21 Jul 2008 18:31 GMT > I guess I've conclusively shown that either .NET is fried, or > something else is causing this issue (i.e. me). And I think I may > have found it.... so, hold up... before you waste your time reading my > replies........ I am SO STUPID...
My log files that supposedly were pinning the issue down to the stream.Write() line, which was supposedly hanging up, actually pinned it down to two functions... the Write() call AND an encryption function made my yours truly, which was entering an INFINITE LOOP... yeah, really.
So my first mistake was not testing my encryption function. My second mistake was that the log files didn't pin down the EXACT line of code of the error. How I did this, I don't know.
Sorry for wasting your time.
Zytan
Peter Duniho - 21 Jul 2008 18:39 GMT > [...] > My log files that supposedly were pinning the issue down to the > stream.Write() line, which was supposedly hanging up, actually pinned > it down to two functions... the Write() call AND an encryption > function made my yours truly, which was entering an INFINITE LOOP... > yeah, really. I'm glad you were able to find the issue. Not to belabor the point, but...had you posted a concise-but-complete code sample that demonstrated the problem, the above may well have been noted by someone else (possibly even me :) ), leading to a quicker solution.
In other words, this is exactly why it's so important to post actual, real-world code. Without the code, no one can say what's wrong, nor even confirm that _your_ code is correct.
Pete
Zytan - 21 Jul 2008 18:58 GMT > I'm glad you were able to find the issue. Not to belabor the point, > but...had you posted a concise-but-complete code sample that demonstrated > the problem, the above may well have been noted by someone else (possibly > even me :) ), leading to a quicker solution. No, belabor away, you're completely right.
I posted in the hopes of wondering if someone could uncover any gotchas about TcpClient. I was just being stupid. As soon as it didn't return after the timeout, I should have known that something else was causing the delay.
And yes, if I posted even a small snippet of code, you would have asked me WTF is that encryption function doing, and I would have said "aha"...
Zytan
Zytan - 21 Jul 2008 19:19 GMT > ......an encryption > function made my yours truly, which was entering an INFINITE LOOP... The bug was operator precedence, I had something like: x << 1 + 1 assuming it would do: (x << 1) + 1 but in fact, it does: x << (1 + 1)
VC++ warns about this, because I do this ALL the time, since I assume << and >> are multiplication and division in my head, which comes first. C# does not give any warning.
Zytan
Peter Duniho - 21 Jul 2008 19:35 GMT >> ......an encryption >> function made my yours truly, which was entering an INFINITE LOOP... [quoted text clipped - 9 lines] > << and >> are multiplication and division in my head, which comes > first. C# does not give any warning. For what it's worth, if "in your head" you are using the shift operators as division and multiplication, you should use division and multiplication operators instead.
Being careful about operator precedence is obviously important in any case, but in this particular situation, using actual multiplication or division operators may well have avoided the bug, as well as made the code more clear as to the intent.
Either way, it's the mixing of math and bit-twiddling that was your problem. The "+ 1" (as opposed to "| 1") suggests this is more about math than bit-twiddling, which would mean it's a multiplication disguised as a shift operation. But even if you really should have been using << with | (i.e. it's bit-twiddling) you wouldn't have had the bug had you used the correct operators together, since the << operator _does_ have higher precedence than the | operator.
Of course, never any harm in providing explicit precedence via parentheses. But I still think it's better to use math operators for math and bit-twiddling operators for bit-twiddling. :)
Pete
Zytan - 21 Jul 2008 20:11 GMT > For what it's worth, if "in your head" you are using the shift operators > as division and multiplication, you should use division and multiplication > operators instead. Right.
> Being careful about operator precedence is obviously important in any > case, but in this particular situation, using actual multiplication or > division operators may well have avoided the bug, as well as made the code > more clear as to the intent. Yup.
> Either way, it's the mixing of math and bit-twiddling that was your > problem. The "+ 1" (as opposed to "| 1") suggests this is more about math [quoted text clipped - 3 lines] > correct operators together, since the << operator _does_ have higher > precedence than the | operator. Ah.
I was doing bit-twiddling, and not math. So, I should be using << with |, just like you say.
I know I'm not the only one who got hit with mixing << and +, though, since VC++ has a warning about it. But, this doesn't negate all the great points you've made.
> Of course, never any harm in providing explicit precedence via > parentheses. Right, I find myself doing this a lot. Why didn't I this time? Probably tired and pressured for time.
> But I still think it's better to use math operators for math > and bit-twiddling operators for bit-twiddling. :) Of course. I had never before thought about +1 and |1 as being any different when the 1st bit is known to be cleared... but it makes perfect sense to think about it in the way you mention....
Great tips! I'm glad I reported the bug now.
Zytan
Peter Duniho - 21 Jul 2008 20:17 GMT > [...] > Great tips! I'm glad I reported the bug now. Glad to help. As the saying goes, I learn far more from my mistakes than from my successes. I feel like I know a lot, so you can only imagine how many mistakes it took to get to this point. And I intend to make a LOT more mistakes before I'm done. Otherwise, how will I learn. :)
Pete
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|