在Java Socket上设置源端口?
我是套接字编程的新手:
是否可以在Java Socket上显式设置源端口?
我正在开发一个客户端/服务器应用程序,客户端可能会在几个端口上侦听来自服务器的回复。 如果我可以在初始化Socket时在客户端设置此回复端口,那将是很好的,这样服务器就能够确定在另一端回复哪个端口。
是的,使用
方法。 这反映了大多数C级套接字实现中可用的bind()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”,则只会收到在此类地址上收听的请求。