在Java Socket上设置源端口?

我是套接字编程的新手:

是否可以在Java Socket上显式设置源端口?

我正在开发一个客户端/服务器应用程序,客户端可能会在几个端口上侦听来自服务器的回复。 如果我可以在初始化Socket时在客户端设置此回复端口,那将是很好的,这样服务器就能够确定在另一端回复哪个端口。

是的,使用bind()方法。 这反映了大多数C级套接字实现中可用的bind()函数。 请注意,您无法始终自由选择要使用的端口,在某些系统上,某些范围会被保留并被视为对用户应用程序的禁止。

它通常是这样的:

首先,服务器在众所周知的端口上打开ServerSocket并等待输入。

同时,客户端打开一个(客户端)Socket,其中包含服务器主机名和这个众所周知的端口地址。 它向服务器发送请求消息以初始化通信会话。

服务器接收消息,生成一个工作线程,该线程在另一个端口上打开另一个ServerSocket,服务器发送一个响应,它告诉客户端这个端口号。

现在客户端关闭实际的连接并创建一个新的Socket,现在使用他刚刚被告知的端口号。

这样,服务器一次可以处理多个客户端,因为每个客户端都获得了他自己的“连接”(端口)。

使用数据报套接字时,发送数据报时,套接字会设置源地址和端口。

 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在这个例子中有点多余, new DatagramSocket(sourcePort)将绑定到首选的最佳选择地址,但是如果除了端口之外还需要指定源IP,那就是这样。

对于这两种类型的套接字,使用bind(new InetSocketAddress(port))将选择适当的本地源地址和指定的端口,端口0也将选择适当的本地端口。

所有可以使用getLocalAddress()getLocalPort()检索。

您可以使用此调用来创建套接字,

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

这通常是针对UDP完成的,不建议用于TCP连接。 如果在两端为TCP执行此操作,则只能有一个TCP连接。 如果再创建一个,套接字层将会混淆,最终会丢失所有连接。

对于TCP,通常的做法是以相同的连接进行回复。 如果您必须使用其他连接进行回复,请在客户端上使用预定义的端口。

首先,我将完全建议您使用Java NIO。

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

其次,通过使用绑定到套接字地址,您还可以定义要连接到的网络地址。 这意味着如果将BIND_ADDRESS设置为“0.0.0.0”,您将能够从连接到服务器的每个网卡进行监听; 但是如果将BIND_ADDRESS设置为“10.190.0.1”,则只会收到在此类地址上收听的请求。