Re: Possible bug in .Net 2.0 udp sockets?



"Redge" <i.really@xxxxxxxxx> wrote in message
news:OXAMtUE6GHA.4996@xxxxxxxxxxxxxxxxxxxxxxx
Thanks for your comments!

You're very welcome. Sorry I haven't been more help so far.

You are of course right, and in my real application, I do not make the
assumption that the port which the client sees is the same as the port
that the server sees. But my real application showed the behaviour that
some clients received the WRONG data, which lead me to the assumption
that something with the endpoints went wrong.

Okay...thanks for explaining that.

Perhaps you can clarify on what output exactly is incorrect. I can't tell
for sure (though I can guess) from your original post or other comments, so
maybe you can answer the question:

When the ID sent by the test application does not match the port number
returned by EndReceiveFrom, which one is actually incorrect? That is, is
the data in the datagram corrupted, resulting in the wrong ID in the
datagram? Or is EndReceiveFrom returning the wrong port? And if
EndReceiveFrom is returning the wrong port, is it just the port that's
wrong, or is the IP address also incorrect?

[...]
Yeah, I perfectly agree with you in this point. To be honest, I never
quite understood why it is necessary to give an EndPoint as "ref" to
both BeginReceiveFrom() AND EndReceiveFrom() -- it's unclear to me
either how those two interact.

Do you ever look at the EndPoint that you passed to BeginReceiveFrom? If
not, you should. It would be interesting to know whether it ever gets set
to something other than the default value you gave it before calling
BeginReceiveFrom, and if so whether it looks anything like what
EndReceiveFrom returns, and/or matches the port derived from the received
datagram.

3) As a minor stylistic point, I'll suggest that you not use the "as"
operator to cast objects that you know in advance should always be
castable.
If you *do* use the "as" operator, you should always check for a null
value
after the cast. If you don't check for null, you'll just get an
exception
anyway, but it won't be the most direct, useful exception you could have
gotten (as compared to the invalid type exception you'd get casting
normally). I prefer to only use the "as" operator when getting a null
result is a normal possibility for which I'm prepared.

You are of course perfectly right. I omitted the error checking in the
code only to not distract too much from my real problem -- in my main
application, I do of course check for a null value after the cast.

Well, my point was more that I personally prefer to not bother checking for
"null" unless that's a normal, expected result from my code. This is a
situation in which "null" should never be returned, so you may not be able
to really do much of anything useful if you do get "null" back.

If you get "null" back, it means something went really wrong and you'll
probably have to stop the program, or at least start again from scratch.

That sort of situation is, to me, a perfect example of one that would be
better dealt with using an exception. I used to avoid exception handling as
much as possible when writing C and C++ code (for a variety of reasons).
But there's no way to turn it off in C#, and it does have certain benefits.
One of them being that you don't have to write any code to handle these
sorts of cases. You just code for the expected case, and let an exception
occur if you've got something really bad going on.

That said, it was strictly a stylistic suggestion. There's not really a
good argument for using one over another...it's more a matter of preference
IMHO. And if you want to get *really* defensive with your coding (that is,
"code defensively"), if you think you can recover gracefully from an
incorrect type cast there (resulting in a null reference), I think it
actually makes more sense to stick with what you've got.

Exactly, and the problem really does only occur when there is more than
one listener. As my server application uses the architecture proposed by
another posting anyway (adding the data to a queue which is then
processed in another thread, leaving the socket in a listening state for
as long as possible), I will change it to use only one listener.

Sounds good. I agree with the other suggestion that it's better for your
i/o and processing to be decoupled. Even if it were possible to have
multiple receives posted to a given socket at once, this would be desirable.
And of course, given the issue you're running into, it's even more so. :)

Using
the workloads I am able to reproduce artificially, I does not seem to
reduce the amount of received packets -- I just don't know if it stays
this way when hundreds of clients are connected; but I suppose it won't
be a problem.

IMHO, if the most you're going to be dealing with is hundreds of clients,
you're unlikely to ever see any real performance issues, assuming you're
running on modern x86 hardware.

As I already said, as this way of handling the data was
proposed by an msdn article, I thought it was a common way of doing so,
and that's why I was quite astonished that the problem with the wrong
endpoints had not attracted someone else's attention before mine.

Well, as you've found, this appears to be unique to .NET 2.0. Perhaps the
article you referenced was written before .NET 2.0 was released?

As I've said, I'm not aware of any reason that multiple receives should
cause a problem. With IOCP that is. As far as I know, that's not only
supported, it's considered good programming practice. But: I have no
guarantee that when you call BeginReceiveFrom using a UDP socket, that you
really wind up using IOCP for those receives. And if it's NOT using IOCP,
then having multiple receives outstanding IS a very big problem.

It all depends on what's going on "under the hood", and it may be that
something changes from 1.1 to 2.0 in which what goes on "under the hood"
makes this problematic for 2.0 when it wasn't for 1.1.

For what it's worth, I posted a question to some other folks who do use IOCP
on a regular basis, and who can problem tell me for sure whether multiple
receives for UDP sockets is valid on IOCP. I don't see any reason it
shouldn't be, but they will be able to confirm that. If so, then I'd say
it's a safe bet that .NET isn't using IOCP in your situation. Whether
that's because it's a UDP socket, or because you have something else going
on with your configuration, or the documentation that claims that the .NET
Sockets use IOCP for the async pattern, I can't say. Any of those might be
possible.

I realize it's all pretty much academic at this point, but if I come across
anything else useful I'll post it back to this thread.

Pete


.



Relevant Pages

  • Re: SetSockOpt with SO_REUSEADDR parameter
    ... Why is it so important to you to use the SAME source port number for all clients? ... I simply do not believe your boss told you to use the same server socket and port number for all client streaming data. ... I want to add the UDP socket into this architecture to send real-time frames. ...
    (microsoft.public.vc.mfc)
  • sockets: connecting several UDP clients
    ... I've got a program that accepts TCP connections. ... It also reads from a UDP socket. ... Now, I want my program not only to communicate via TCP, but also talk to each of the accepted clients via UDP. ... My server reads from port 5555. ...
    (comp.os.linux.development.apps)
  • Re: adding machine to domain with NATed IPs
    ... sounds that the DCs are not reaching the clients ... weight 100, port 389, target srv5.mydomain.local ...
    (microsoft.public.windows.server.active_directory)
  • Re: adding machine to domain with NATed IPs
    ... sounds that the DCs are not reaching the clients ... Type: SRV (Service location) ... weight 100, port 389, target srv5.mydomain.local ...
    (microsoft.public.windows.server.active_directory)
  • Re: DDoS to microsoft sites
    ... The primary difference between the two clients is that the first port scan I ... > - netbios (brute force attack on Administrator account) ... I'm guessing that the SQL server is the infection vector in both these ...
    (Incidents)

Loading