UDP server (in Java)

P

Peter Ashford

Hi,

A question for the list: in a TCP client/server model, the server will
wait accepting new connections on a well known port. New connections
are mapped onto a new port and handled seperately through that.

I was writing a UDP client/server and it occurs to me that I don't know
how to do the same thing. Is it possible? The problem is that my
initial thought was to send the client back the port number of a new
port to connect to which the server could listen to for that client's
connection - but that means the client would have to connect to an
arbitrary UDP port. I would like to have one well known port to connect
to (so machines with firewalls can punch a hole through for that
specific port), but connections to arbitrary ports is not at all
firewall friendly.

What to do? How do games which use UDP in a client/server arangement
solve this problem?

This going to the Java programming NG because that's what I'm coding in,
but I'm not sure that this is especially relevant to the architectural
details.

TIA

Peter.
 
S

Shripathi Kamath

Peter Ashford said:
Hi,

A question for the list: in a TCP client/server model, the server will
wait accepting new connections on a well known port. New connections
are mapped onto a new port and handled seperately through that.

I was writing a UDP client/server and it occurs to me that I don't know
how to do the same thing. Is it possible? The problem is that my
initial thought was to send the client back the port number of a new
port to connect to which the server could listen to for that client's
connection - but that means the client would have to connect to an
arbitrary UDP port. I would like to have one well known port to connect
to (so machines with firewalls can punch a hole through for that
specific port), but connections to arbitrary ports is not at all
firewall friendly.

What to do? How do games which use UDP in a client/server arangement
solve this problem?

This going to the Java programming NG because that's what I'm coding in,
but I'm not sure that this is especially relevant to the architectural
details.


Yes, this is indeed possible.

Two hints:

a. Look at the DatagramSocket(int port) constructor
b. Look at the TFTP protocol RFCs 783 and 1350.

You have some design issues to consider in order to handle multiple
'clients'.

HTH,
 
P

Peter Ashford

Shripathi said:
Yes, this is indeed possible.

Two hints:

a. Look at the DatagramSocket(int port) constructor
b. Look at the TFTP protocol RFCs 783 and 1350.

You have some design issues to consider in order to handle multiple
'clients'.

I dont see how that helps - TFTP uses TIDs to declare the source and
destination ports to use between them - this is the situation I wanted
to avoid - they will continue by opening new (arbitrary) UDP ports, so a
firewall administrator would hae no choice but to open up all UDP ports
in order to make this protocol work.

I suppose if the server sends back a new port for the client to connect
to, that the client firewall would be required to be permissive with
outgoing UDP packets, which isn't as bad as being permissive with
incoming UDP packets.

The thing is, in TCP the originating packet goes to (and arrives at) a
well known port, so can be a single open point on both firewalls. But
when TCP accepts and hands off to another port, firewalls typically can
recognise this as a related packet to the existing TCP connection and
therefore allow it to continue. It's *this* kind of functionality I'd
like to achieve, so neither end has to open up a firewall to an
arbitrary range of UDP ports.

Cheers,

Peter.
 
S

Shripathi Kamath

I dont see how that helps - TFTP uses TIDs to declare the source and
destination ports to use between them - this is the situation I wanted
to avoid - they will continue by opening new (arbitrary) UDP ports, so a
firewall administrator would hae no choice but to open up all UDP ports
in order to make this protocol work.

I suppose if the server sends back a new port for the client to connect
to, that the client firewall would be required to be permissive with
outgoing UDP packets, which isn't as bad as being permissive with
incoming UDP packets.

The thing is, in TCP the originating packet goes to (and arrives at) a
well known port, so can be a single open point on both firewalls. But
when TCP accepts and hands off to another port, firewalls typically can
recognise this as a related packet to the existing TCP connection and
therefore allow it to continue. It's *this* kind of functionality I'd
like to achieve, so neither end has to open up a firewall to an
arbitrary range of UDP ports.


Like I said you have some design decisions to make. TFTP was an example
because, I have setups with a firewall that lets 'connections' from outside
the firewall work.

*A* way to do what you want is to have just the *one* port on the server,
and have all clients send and receive datagrams from it. That would be as
close to a TCP ServerSocket as you could get.

Of course you'll need to decide on whether you wish to spawn threads for
each client (distinguished on IP address + port) that sends datagrams to the
server socket, or handle it in one thread, etc.
 
P

Peter Ashford

Like I said you have some design decisions to make. TFTP was an example
because, I have setups with a firewall that lets 'connections' from outside
the firewall work.

*A* way to do what you want is to have just the *one* port on the server,
and have all clients send and receive datagrams from it. That would be as
close to a TCP ServerSocket as you could get.

Of course you'll need to decide on whether you wish to spawn threads for
each client (distinguished on IP address + port) that sends datagrams to the
server socket, or handle it in one thread, etc.

Yeah, I did want to have one thread per connection - I'm aiming at a
maximum of about 8 concurrent connections so I didn't wasn't worried
about having too many threads. I suppose I could used multiplexed IO on
the one port instead of having one thread and port per client.
 
G

Gordon Beaton

A question for the list: in a TCP client/server model, the server
will wait accepting new connections on a well known port. New
connections are mapped onto a new port and handled seperately
through that.

That's not correct, there is no new port involved. Every client
connects to and remains connected to the well known port number for
the duration of the connection.
I was writing a UDP client/server and it occurs to me that I don't
know how to do the same thing. Is it possible?

Your server knows the remote IP and port number of every datagram it
recieves, so it can easily tell the clients apart.

/gordon
 
D

David Robbins

Peter Ashford said:
Hi,

A question for the list: in a TCP client/server model, the server will
wait accepting new connections on a well known port. New connections
are mapped onto a new port and handled seperately through that.

I was writing a UDP client/server and it occurs to me that I don't know
how to do the same thing. Is it possible? The problem is that my
initial thought was to send the client back the port number of a new
port to connect to which the server could listen to for that client's
connection - but that means the client would have to connect to an
arbitrary UDP port. I would like to have one well known port to connect
to (so machines with firewalls can punch a hole through for that
specific port), but connections to arbitrary ports is not at all
firewall friendly.

What to do? How do games which use UDP in a client/server arangement
solve this problem?

This going to the Java programming NG because that's what I'm coding in,
but I'm not sure that this is especially relevant to the architectural
details.

TIA

Peter.

one basic think that other replies have missed... at the socket level udp
'connections' aren't really connections. udp is a connectionless protocol
so each end listens on the port and processes whatever it hears but there is
no connection involved for the socket. so one socket listening on any given
port can receive from any number of clients. you have to track who you are
talking to in the application by getting the ip address of the remote
station from the header.

On the application level you will probably end up with one thread receiving
the packets from the socket, reading the ip address of the remote station
and passing the data to the right thread to process that client.

detecting new clients and figuring out when they leave is another problem
since the protocol doesn't provide for connect and disconnect handshakes
either.

also of course there is no ack and retry mechanism like in tcp connections,
so you have to have your own method of verifying receipt if needed.
 
P

Peter Ashford

Gordon said:
That's not correct, there is no new port involved. Every client
connects to and remains connected to the well known port number for
the duration of the connection.

It's possible the Java docs are incorrect, but this is what it has to
say about TCP accept:

"Upon acceptance, the server gets a new socket bound to a different
port. It needs a new socket (and consequently a different port number)
so that it can continue to listen to the original socket for connection
requests while tending to the needs of the connected client."
Your server knows the remote IP and port number of every datagram it
recieves, so it can easily tell the clients apart.

Yes, I know that.

I've written TCP/IP client servers before and always believed that what
the Java docs mentioned (above) was correct - that a new socket is
created on accept bound to a new port. BTW: I have written far more
client / servers in C/C++ than in Java, so it's also on the basis of the
Unix networking docs and the Windsock docs that I've formed my beliefs
about the way these things work.

Either I've misunderstood the docs, or TCP can create a related socket
on accept. (And I know that firewalls understand the concept of
'related' packets in TCP/IP)

I note that unix man pages for accept says:

"Accept extracts the first connection on the queue of pending
connections, creates a new socket with the same properties of s and
allocates a new file descriptor for the socket. "

Which doesn't mention a new port but does mention a new socket. Which
of these is correct?

I'm a confused little programmer :eek:)

Peter.
 
D

David Robbins

Peter Ashford said:
It's possible the Java docs are incorrect, but this is what it has to
say about TCP accept:

"Upon acceptance, the server gets a new socket bound to a different
port. It needs a new socket (and consequently a different port number)
so that it can continue to listen to the original socket for connection
requests while tending to the needs of the connected client."


Yes, I know that.

I've written TCP/IP client servers before and always believed that what
the Java docs mentioned (above) was correct - that a new socket is
created on accept bound to a new port. BTW: I have written far more
client / servers in C/C++ than in Java, so it's also on the basis of the
Unix networking docs and the Windsock docs that I've formed my beliefs
about the way these things work.

Either I've misunderstood the docs, or TCP can create a related socket
on accept. (And I know that firewalls understand the concept of
'related' packets in TCP/IP)

I note that unix man pages for accept says:

"Accept extracts the first connection on the queue of pending
connections, creates a new socket with the same properties of s and
allocates a new file descriptor for the socket. "

Which doesn't mention a new port but does mention a new socket. Which
of these is correct?

I'm a confused little programmer :eek:)

Peter.

remember, tcp is different than udp which was the original question. in udp
there are no connections on the socket level, making and tracking
'connections' using udp would be up to the application.

in tcp if you are going to accept multiple connection on a given port you
essentially get a clone of the listening socket for each connection, they
all use the same port number but are differentiated by the client ip/port
they are connected to.
 
D

David Robbins

Peter Ashford said:
Hi,

A question for the list: in a TCP client/server model, the server will
wait accepting new connections on a well known port. New connections
are mapped onto a new port and handled seperately through that.

I was writing a UDP client/server and it occurs to me that I don't know
how to do the same thing. Is it possible? The problem is that my
initial thought was to send the client back the port number of a new
port to connect to which the server could listen to for that client's
connection - but that means the client would have to connect to an
arbitrary UDP port. I would like to have one well known port to connect
to (so machines with firewalls can punch a hole through for that
specific port), but connections to arbitrary ports is not at all
firewall friendly.

What to do? How do games which use UDP in a client/server arangement
solve this problem?

This going to the Java programming NG because that's what I'm coding in,
but I'm not sure that this is especially relevant to the architectural
details.

TIA

Peter.


one basic think that other replies have missed... at the socket level udp
'connections' aren't really connections. udp is a connectionless protocol
so each end listens on the port and processes whatever it hears but there is
no connection involved for the socket. so one socket listening on any given
port can receive from any number of clients. you have to track who you are
talking to in the application by getting the ip address of the remote
station from the header.

On the application level you will probably end up with one thread receiving
the packets from the socket, reading the ip address of the remote station
and passing the data to the right thread to process that client.

detecting new clients and figuring out when they leave is another problem
since the protocol doesn't provide for connect and disconnect handshakes
either.

also of course there is no ack and retry mechanism like in tcp connections,
so you have to have your own method of verifying receipt if needed.

(sri i am reposting this, my list of groups was incomplete so it didn't get
to both of the poster's groups).
 
D

David Robbins

Peter Ashford said:
It's possible the Java docs are incorrect, but this is what it has to
say about TCP accept:

"Upon acceptance, the server gets a new socket bound to a different
port. It needs a new socket (and consequently a different port number)
so that it can continue to listen to the original socket for connection
requests while tending to the needs of the connected client."


Yes, I know that.

I've written TCP/IP client servers before and always believed that what
the Java docs mentioned (above) was correct - that a new socket is
created on accept bound to a new port. BTW: I have written far more
client / servers in C/C++ than in Java, so it's also on the basis of the
Unix networking docs and the Windsock docs that I've formed my beliefs
about the way these things work.

Either I've misunderstood the docs, or TCP can create a related socket
on accept. (And I know that firewalls understand the concept of
'related' packets in TCP/IP)

I note that unix man pages for accept says:

"Accept extracts the first connection on the queue of pending
connections, creates a new socket with the same properties of s and
allocates a new file descriptor for the socket. "

Which doesn't mention a new port but does mention a new socket. Which
of these is correct?

I'm a confused little programmer :eek:)

Peter.
remember, tcp is different than udp which was the original question. in udp
there are no connections on the socket level, making and tracking
'connections' using udp would be up to the application.

in tcp if you are going to accept multiple connection on a given port you
essentially get a clone of the listening socket for each connection, they
all use the same port number but are differentiated by the client ip/port
they are connected to.
 
G

Gordon Beaton

It's possible the Java docs are incorrect, but this is what it has
to say about TCP accept:

"Upon acceptance, the server gets a new socket bound to a different
port. It needs a new socket (and consequently a different port
number) so that it can continue to listen to the original socket for
connection requests while tending to the needs of the connected
client."

The Java networking tutorial is wrong. This comes up here (c.l.j.p) on
a regular basis. For years Sun has been ignoring corrections sent to
them.
Which doesn't mention a new port but does mention a new socket.
Which of these is correct?

New socket descriptor - yes. New port number - no.

The thing to realize is that a TCP connection consists of two IP
addresses and two port numbers. So two connections can be unique even
though they use the same port number at the server. The connection
created by accept() inherits the initial local IP+port from the
original listening socket, and the remaining two fields come from the
connecting remote.

You can confirm that the port number doesn't change with tools like
netstat or tcpdump, or you can ask the socket at either end of the
connection to report its port number and/or remote port number.

In UDP you obviously have to implement these mechanisms yourself, but
it is a simple matter to keep your client "connections" distinct in a
similar manner. You don't get a new descriptor each time a new client
starts to communicate with you, but you can keep them distinct anyway
by using the remote IP and port number, for example as a hash key. I
guess you *could* negotiate with each new client to communicate
through a unique, per-client socket (reserving the original one just
for new "connections"), but it really isn't necessary to do it that
way.

/gordon
 
S

Steve Horsley

Peter said:
It's possible the Java docs are incorrect, but this is what it has to
say about TCP accept:

"Upon acceptance, the server gets a new socket bound to a different
port. It needs a new socket (and consequently a different port number)
so that it can continue to listen to the original socket for connection
requests while tending to the needs of the connected client."

Gordon is correct, and the java tutorial is wrong.

I advise against using TFTP's approach of port hopping. It is confusing
to both analysers and firewalls.

You could simply use the IP address of the "other party" as a session
ID, or if there is the possibility of more than one session from the
same other IP address, negotiate a session ID for each session.

Steve
 
P

Peter Ashford

Gordon said:
The Java networking tutorial is wrong. This comes up here (c.l.j.p) on
a regular basis. For years Sun has been ignoring corrections sent to
them.

Bugger. Okay, well thanks for clearing that up for me - I've laboured
under that misaprehension for years :eek:)
New socket descriptor - yes. New port number - no.

The thing to realize is that a TCP connection consists of two IP
addresses and two port numbers. So two connections can be unique even
though they use the same port number at the server. The connection
created by accept() inherits the initial local IP+port from the
original listening socket, and the remaining two fields come from the
connecting remote.

You can confirm that the port number doesn't change with tools like
netstat or tcpdump, or you can ask the socket at either end of the
connection to report its port number and/or remote port number.

In UDP you obviously have to implement these mechanisms yourself, but
it is a simple matter to keep your client "connections" distinct in a
similar manner. You don't get a new descriptor each time a new client
starts to communicate with you, but you can keep them distinct anyway
by using the remote IP and port number, for example as a hash key. I
guess you *could* negotiate with each new client to communicate
through a unique, per-client socket (reserving the original one just
for new "connections"), but it really isn't necessary to do it that
way.

Ah, ok, thank you very much that clears it up for me. Bugger the Sun
documents, that had me entirely on the wrong track :eek:)

Cheers!

Peter.
 
P

Peter Ashford

Steve said:
Gordon is correct, and the java tutorial is wrong.

I advise against using TFTP's approach of port hopping. It is confusing
to both analysers and firewalls.

You could simply use the IP address of the "other party" as a session
ID, or if there is the possibility of more than one session from the
same other IP address, negotiate a session ID for each session.

I will use that approach - I only need to handle one connection per
client machine
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top