When will one socket suffice, when do I need to create more?
The "connectionless" aspect of UDP has thrown me for a loop...
If I setup a UDP socket set to INADDR_ANY, then bind that to port 33445 on the local machine, the machine will accept incoming connections from various clients. All of these connections will be serviced by that one socket, since this is not TCP and I cannot spawning a new child sockets to handle each connection directly. I am able to reply to any, some, or all of these connected clients, from their latest message.
So where things get a little fuzzy for me is here...
Am I able to also send out messages at any time to any of these clients? or can I only send messages that in response of recvfrom() ?
Separately, if I wanted that server (while it is serving clie开发者_高级运维nts) to connect to another server and have a conversation about something else, I assume I will need to create a new socket for this purpose? I cannot just use the existing server socket and specify a new destination address?
Many thanks to this wonderful community.
Edit: Let me put it another way.. It seems to be that I can only use the bound socket for responding to clients that have previously reached me on that socket. To initiate a conversation with a new host, I cannot simply use the bound socket for that purpose? I must create a new socket in order to reach a server that is listening, correct?
UDP sockets can operate in two different modes:
- default not-connected mode: all datagrams sent to the port/address of your process are received; you need to specify destination address for each send you do.
- connected mode: only the datagrams sent from the address/port you connected to are received; you don't need to specify destination address on each send.
Here's a small review of connected UDP sockets.
Edit:
Here's a little python UDP server that accepts packets from any client and copies them to a second server. Everything is done with one not-connected UDP socket.
#!/usr/bin/env python
import sys, socket, string
if len( sys.argv ) != 4:
print "Usage: udptee <local-listen-port> <copy-host> <copy-port>"
exit( 1 )
copy = ( sys.argv[2], int( sys.argv[3] ))
s = socket.socket( socket.AF_INET, socket.SOCK_DGRAM )
#s.bind(( 'localhost', int( sys.argv[1] )))
s.bind(( '', int( sys.argv[1] )))
print "listening on ", s.getsockname()
print "copying to", copy
while True:
line, addr = s.recvfrom( 1024 )
print "received: ", line, " from ", addr
s.sendto( line, addr ) # echo to source
s.sendto( line, copy ) # copy to tee
if string.strip( line ) == "exit": break
print "Goodbye and thanks for all the fish"
s.close()
Run it in one terminal as:
~$ ./udptee 9090 <IP-of-copy-server> 9999
Then start netcat
in server mode in second term. This one will accept copies of the datagrams:
# this used to be "nc -ul 127.0.0.1 9999" which only listened on loopback
~$ nc -ul 9999
Start netcat
client in third term to send stuff to the first server:
~$ nc -u <IP-of-tee-server> 9090
Start typing and see both servers echo what you type.
UDP sockets aren't connected to a remote host or client, so all you need to do is to use sendto() using the destination address and the UDP socket you have initialized. So yes, you can send out messages using the UDP socket at any time given that you have set up the UDP socket correctly. Just set the receiving address in the sockaddr struct you are using. If the receiving part have a UDP socket bound on the port you are sending the message, then it will receive it.
On that 2nd question it all depends if the conversation with that 2nd server uses a different port. If it uses the same port then there is no need to create another UDP socket. You just have to separate the messages the server 1 gets from its clients from messages it gets from server 2 somehow.
Ill recommend taking a look at Beej's excellent guide chapter 5.8 and 6.3.
Beej's Guide to Network Programming
精彩评论