0

ソケット I/O に Netty を使用するサーバー タスクがあります。ポート MY_PORT にバインドし、クライアントから 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 );
    }

}
4

2 に答える 2

2

すでにbind()ローカルアドレスの設定に使用しています。特定の宛先ポートに接続するために使用できますconnect()(「接続」の概念の一部)。通常のデータグラムソケットでは、送信要求にリモートポートを含めることができますが、を使用している場合は含めることができませんwrite()。その場合は、を使用する必要がありますconnect()

于 2012-10-04T02:01:18.587 に答える
0

彼らは、私のサーバーがクライアントに送信するUDPメッセージの送信元ポートが、宛先に使用されるものとは異なる場合に役立つと述べました.

これは私には完全にやかましいように聞こえます。ネット管理者は、送信元/宛先ポートが実際にどのように割り当てられているかを知らないようです。クライアントが固定ポートではなくシステム割り当ての Poet を使用したとしても (おそらくそうすべきです)、システムはサーバーが使用しているのと同じポート番号を割り当てることができます。

ただし、クライアントに固定ポートではなくシステム割り当てポートを使用させることで、おそらくそれらをシャットダウンするか、少なくとも別の問題に移すことができます。もちろん、クライアント側のファイアウォールがない限り...

于 2012-10-04T00:43:16.027 に答える