I've开发者_运维问答 got an app that needs to transmit and receive on the same port. This can happen in two cases:
Where the PC is talking to a piece of remote hardware. It "replies to sender", so the datagrams come back in to my PC via the sending port.
Where the PC is talking to itself (loopback mode) for testing and demoing (a test app feeds fake data into our main app via UDP).
This only seems to fail when trying to achieve loopback. The only way I can get it working is to ensure that the receiver is set up first - something I cannot guarantee.
Can anyone help narrow down my search by suggesting a "correct" way to implement the UdpClient(s) to handle the above situations reliably?
(The only solution that I've found to work reliably with the remote hardware is to use a single UdpClient in a bidirectional manner, although I'm working with legacy code that may be influencing that finding. I've tried using two UdpClients, but they step on each others toes - In some cases, once one client is started up, the other client cannot connect. With ExclusiveAddressUse/ReuseAddress set up to allow port sharing, I can almost get it to work, apart from the receiver having to start first)
edit
To elaborate:
We communicate with external hardware via UDP. When it receives comms from us, it replies to the source address - so we receive messages back in on the same port. This part is working fine.
However, if I try to emulate the external hardware using loopback (i.e. I send and receive through the same port "to myself"), I can only receive datagrams if I begin receiving before I begin transmitting. THat works fine - but if I transmit and then try to receive, I never receive any data. What I actually try to send is irrelevant in this case.
So I have two problems:
1) How to manage loopback that works reliably.
2) How to do (1) without breaking the external comms that is currently working fine!
As I've tried all kinds of combinations of 1 or 2 UdpClients and a multitude of different settings (to no avail), I was just wondering if anyone has managed to get UPD loopback working well, as that may give me a lead to a solution that I can get working in all cases.
Thanks for taking the time to think about this...
This is by design.
UDP communication is connection less as compared to TCP which need a connection.
When sending data from UDP it is broadcasted. Which means it will be available only to receiver which are alive at a time of broadcasting.
Example :
TCP is like a phone call. Caller calls receiver. Receiver accepts call and the communication happens. If receiver is not available caller will get a error.(Caller is client and receiver is server listening on a port)
UDP is like FM radio broadcasting. A song is broadcasted on radio irrespective of if anyone is listening on other end or not. If the receivers had put their radio set on they will receive the song. If song is transmitted at 10:30 and my radio set is on at 10:30 , I can hear the song. But if I put my raido set on at 10:35 then it means I have missed it and would not be able to hear it again.
Update
As I can see the real problem is transmitting on port 1111(for example) though application X and receiving on port 1111 through application Y on SAME Machine is what you are trying to achieve.
For the same I can suggest 2 workarounds(not good but workable).
As you said if you start the transmitter after starting the receiver all is fine. So just try and put the logic of RESTARTING the transmitter periodically.
Transmit and receive on 2 ports every time. eg. 1111 and 2222. The remote hardware will use the first set of 1111 and the demoing application will use 2222.
So I think I understand your problem.
You have
1- A client application that sends UDP data to a hardware device that is receiving on say port 1234, at the same time this applications is also receiving responses on port 1234.
2- A hardware device that receives UDP data on port 1234 and responds to the sender on port 1234.
So when you emulate the hardware device using on the same machine you end up with the client application and the hardware emulator both listening for UDP packets on the same ip address 127.0.0.1 and port 1234?
Have I captured the essense of what you have?
If so, have you considered adding a second IP address to the machine. This does not mean that you need to have 2 network cards, one network card can have multiple IP addresses. That way you can have the two "devices" on on a separate interface which should overcome any conflicts having both on the same interface.
For example, if you have the two IP addresses 192.168.0.5
and 192.168.0.6
.
The client application can be sending to 192.168.0.6
and receiving on 192.168.0.5
while the hardware emulator is receiving on 192.168.0.6
and responds to 192.168.0.5
.
Here is a link to describe how to add additional IP addresses.
http://www.itsyourip.com/networking/how-to-add-multiple-ip-address-in-windows-2000xp2003/
This is for 2000/XP/2003 but the process is similar for Vista and Windows 7.
After a long time away from this code, I got a chance to take another look at it, and have worked out the embarrassingly trivial solution to this problem.
It turns out that the client code calling my UDP class was setting it up to both transmit and receive. So instead of having a transmitter with write access and a reciever with read access, I actually had a transmitter with read/write and reciever with read/write.
This meant that if the transmitter was initialised first, it would also attempt to receive on that port, and so it would grab all the datagrams that were transmitted. When the receiver connected, it never received any data simply because it was being consumed by the transmitter.
精彩评论