12

I'm very new to socket programming:

Is it possible to explicitly set the the source port on a Java Socket?

I am working on a client/server application in which clients could potentially be listening for replies from the server on several ports. It would be nice if I could set this reply port on the client side when initializing the Socket, so that the server would be able to determine which port to reply to on the other side.

asked Dec 2, 2009 at 15:38
1
  • Yes, this is possible, but notice that when you also create a server using the same port then you'll need to set the SO_REUSEPORT flag on both the server and the client sockets before being able to bind the second. Commented Sep 17, 2022 at 20:56

5 Answers 5

6

It usually goes like this:

First, the Server opens a ServerSocket on a well known port and waits for input.

Meanwhile the Client opens a (client) Socket with the servers hostname and this well known port address. It sends a request message to the server to initialize a communication session.

The server receives the message, spawns a worker thread, which opens another ServerSocket on a different port and the server sends a response, where it tells the client this port number.

Now the client closes the actual connection and creates a new Socket, now with the port number he has just been told.

This way, the server can handle more then one client at a time, because each client gets his individual 'connection' (port).

answered Dec 2, 2009 at 15:50
Sign up to request clarification or add additional context in comments.

2 Comments

No, there's absolutely no need to open another server just for a single client, and for the client to close the first socket and reconnect to the other server.
But Server socket needs to bind to a new port to make listening port free to accept the next request.
5

Yes, use the (削除) bind() (削除ここまで) method. This mirrors the bind() function available in most C-level socket implementations. Note that you can't always choose freely which port to use, on some system some ranges are reserved and considered off-limits to user applications.

ΦXocę 웃 Пepeúpa ツ
48.4k17 gold badges77 silver badges102 bronze badges
answered Dec 2, 2009 at 15:39

2 Comments

If you bind to port zero can you determine the port bound to using getLocalPort()?
@PP - yes, GetLocalSocketAddress() works too, but may have the wildcard address.
4

When using datagram sockets, the source address and port is set by the socket when the datagram is sent.

InetAddress sourceAddr = InetAddress.getLocalHost();
DatagramSocket sock = new DatagramSocket(sourcePort, sourceAddr);
DatagramPacket msg = new DatagramPacket(mbuf, mbuf.length, dstIP, dstPort);
sock.send(msg); // sent from sourcePort to dstPort

sourceAddr is a little redundant in this example, new DatagramSocket(sourcePort) would bind to the preferred best-choice address, but if you need to specify the source IP in addition to port, that's how.

For both types of socket, using bind(new InetSocketAddress(port)) will choose an appropriate local source address and the specified port, and port 0 will choose an appropriate local port as well.

All retrievable with getLocalAddress() and getLocalPort().

answered Aug 27, 2010 at 17:07

Comments

1

You can use this call to create socket,

public Socket(InetAddress address,
 int port,
 InetAddress localAddr,
 int localPort)
 throws IOException

This is normally done for UDP and this is not advised for TCP connections. If you do this for TCP on both ends, you can only have one TCP connection. If you create one more, the socket layer will get confused and you will end up lose all your connections.

For TCP, the common practice is to reply in the same connection. If you have to reply in a different connection, use a pre-defined ports on client also.

answered Dec 2, 2009 at 15:48

1 Comment

InetAddress is package private. this is the same non answer as the rest of the internet. what is the secret. please tell me the secret, as without the secret i cant use this information
1

First, I will totally recomend you to use Java NIO.

DatagramChannel udpchannel = DatagramChannel.open();
DatagramSocket udpsocket = udpchannel.socket();
SocketAddress sa = new InetSocketAddress(BIND_ADDRESS, BIND_PORT);
udpsocket.bind(sa);

Second, by using the binding to a socket address you will also be able to define to which network address you will be connected to. It means that if you set BIND_ADDRESS to "0.0.0.0" you will be able to listen from every network card connected to your server; but if you set BIND_ADDRESS to, for example, "10.190.0.1" you will only receive requests listened on such address.

answered Dec 2, 2009 at 16:01

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.