Java 如何为使用Netty发送UDP数据包的服务器配置源端口?

Java 如何为使用Netty发送UDP数据包的服务器配置源端口?,java,udp,netty,Java,Udp,Netty,我有一个服务器任务,它使用Netty进行套接字I/O。它绑定到端口MY_端口并从客户端接收UDP消息。它响应这些客户机,将消息发送回目标端口为MY_port的客户机。使用wireshark,我看到来自服务器的传出数据包也有一个源端口my_port。这一切都很好 负责服务器和客户端之间网络的人员在负载平衡器方面遇到了一些问题。他们说,如果我的服务器发送给客户端的UDP消息的源端口与用于目的地的端口不同,这将对他们有所帮助 我已经看过Netty API,但我不确定如何才能做到这一点。似乎因为我绑定了

我有一个服务器任务,它使用Netty进行套接字I/O。它绑定到端口MY_端口并从客户端接收UDP消息。它响应这些客户机,将消息发送回目标端口为MY_port的客户机。使用wireshark,我看到来自服务器的传出数据包也有一个源端口my_port。这一切都很好

负责服务器和客户端之间网络的人员在负载平衡器方面遇到了一些问题。他们说,如果我的服务器发送给客户端的UDP消息的源端口与用于目的地的端口不同,这将对他们有所帮助

我已经看过Netty API,但我不确定如何才能做到这一点。似乎因为我绑定了一个本地端口,所以我也必须将其用于传出数据包??这是我的代码的精简版本

import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.UnknownHostException;
import java.util.concurrent.Executors;

import org.jboss.netty.bootstrap.ConnectionlessBootstrap;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelHandler;
import org.jboss.netty.channel.socket.nio.NioDatagramChannelFactory;

public class UdpServer {

    private final int port;
    private Channel serverChannel;

    public UdpServer( int port ) {
        super();
        this.port = port;
    }

    public void start() {
        NioDatagramChannelFactory serverChannelFactory =
            new NioDatagramChannelFactory( Executors.newCachedThreadPool(), 1 );
        ConnectionlessBootstrap serverBootstrap =
            new ConnectionlessBootstrap( serverChannelFactory );
        serverBootstrap.setPipelineFactory( new ChannelPipelineFactory() {
            @Override
            public ChannelPipeline getPipeline() {
                return Channels.pipeline( new SimpleChannelHandler() {
                    @Override
                    public void messageReceived( ChannelHandlerContext ctx,
                        MessageEvent e ) {
                        // TODO, handle message from client
                    }
                } );
            }
        } );
        serverBootstrap.setOption( "reuseAddress", Boolean.TRUE );
        final InetSocketAddress trafficAddress = new InetSocketAddress( port );
        serverChannel = serverBootstrap.bind( trafficAddress );
    }

    public void sendMessage( byte[] message, String clientIp )
        throws UnknownHostException {
        // TODO, how do I control the source port of this packet??
        SocketAddress address =
            new InetSocketAddress( InetAddress.getByName( clientIp ), port );
        ChannelBuffer buffer = ChannelBuffers.wrappedBuffer( message );
        serverChannel.write( buffer, address );
    }

}
他们说,如果我的服务器发送给客户端的UDP消息的源端口与用于目的地的端口不同,这将帮助他们解决问题

对我来说,这听起来像是彻头彻尾的胡说八道。Net管理员似乎不知道如何实际分配源/目标端口。即使客户端使用的是系统分配的端口,而不是他们可能应该使用的固定端口,系统仍然可以分配与服务器使用的端口号相同的端口号


但是,通过让客户端使用系统分配的端口而不是固定端口,您可能会关闭它们,或者至少将它们转移到另一个问题上。当然,除非有客户端防火墙……

您已经在使用
bind()
设置本地地址。您可以使用
connect()
连接到特定的目标端口(“连接”概念的延伸)。在常规数据报套接字上,您可以在发送请求中包含远程端口,但如果您使用的是
write()
,则不能。在这种情况下,您必须使用
connect()

是的,我也有同样的想法。不幸的是,我无法控制这个系统中的客户端,而且系统中有防火墙,因此需要固定端口。因此,我仍然需要bind()调用来接收流量,但不使用从它返回的通道对象。相反,每次我想向客户端发送东西时,我都会调用connect()?如果我有1000个客户端,我要么保留所有这些通道对象,要么在每次发送消息时创建一个新的通道对象,这两种方法都显得效率低下。我的理解正确吗?