在 Java Socket 上设置源端口?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1833690/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Setting source port on a Java Socket?
提问by AndreiM
I'm very new to socket programming:
我对套接字编程很陌生:
Is it possible to explicitly set the the source port on a Java Socket?
是否可以在 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.
我正在开发一个客户端/服务器应用程序,其中客户端可能会在多个端口上监听来自服务器的回复。如果我可以在初始化 Socket 时在客户端设置此回复端口,那么服务器将能够确定在另一端回复哪个端口,那就太好了。
采纳答案by unwind
Yes, use the
method. This mirrors the bind()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.
是的,使用
方法。这反映了bind()bind()
大多数 C 级套接字实现中可用的函数。请注意,您不能总是自由选择要使用的端口,在某些系统上,某些范围被保留并被认为是用户应用程序的禁区。
回答by ZZ Coder
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.
这通常用于 UDP,不建议用于 TCP 连接。如果对两端的 TCP 都这样做,则只能有一个 TCP 连接。如果你再创建一个,socket 层会变得混乱,你最终会失去所有的连接。
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.
对于 TCP,通常的做法是在同一个连接中回复。如果您必须在不同的连接中回复,也请使用客户端上的预定义端口。
回答by Andreas Dolk
It usually goes like this:
它通常是这样的:
First, the Server opens a ServerSocket on a well known port and waits for input.
首先,服务器在一个众所周知的端口上打开一个 ServerSocket 并等待输入。
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.
服务器接收到消息,产生一个工作线程,它在不同的端口上打开另一个 ServerSocket,服务器发送一个响应,在那里它告诉客户端这个端口号。
Now the client closes the actual connection and creates a new Socket, now with the port number he has just been told.
现在客户端关闭实际连接并创建一个新的 Socket,现在使用他刚刚被告知的端口号。
This way, the server can handle more then one client at a time, because each client gets his individual 'connection' (port).
这样,服务器一次可以处理多个客户端,因为每个客户端都有自己的“连接”(端口)。
回答by Oso
First, I will totally recomend you to use Java NIO.
首先,我会完全推荐你使用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.
其次,通过使用与套接字地址的绑定,您还可以定义要连接到的网络地址。这意味着如果您将 BIND_ADDRESS 设置为“0.0.0.0”,您将能够从连接到您服务器的每个网卡上进行监听;但是,如果您将 BIND_ADDRESS 设置为例如“10.190.0.1”,您将只会收到在此类地址上侦听的请求。
回答by davenpcj
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.
sourceAddr
在这个例子中有点多余,new DatagramSocket(sourcePort)
将绑定到首选的最佳选择地址,但是如果除了端口之外还需要指定源 IP,就是这样。
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.
对于这两种类型的套接字, usingbind(new InetSocketAddress(port))
会选择一个合适的本地源地址和指定的端口,端口 0 也会选择一个合适的本地端口。
All retrievable with getLocalAddress()
and getLocalPort()
.
所有都可以用getLocalAddress()
和检索getLocalPort()
。