我有一個使用套接字I/O的Netty的服務器任務。它綁定到端口MY_PORT並從客戶端接收UDP消息。它響應這些客戶端,將消息發送回目標端口爲MY_PORT的客戶端。使用wireshark,我發現從我的服務器發出的數據包也有一個源端口MY_PORT。這一切工作正常。如何配置使用Netty發送UDP數據包的服務器的源端口?
服務器和客戶端之間的網絡負責人在負載均衡器中遇到了一些問題。他們說如果我的服務器發送給客戶端的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);
}
}
所以,我仍然需要bind()調用來接收流量,但不使用從它返回的Channel對象。相反,每次我想將某個東西發送給客戶端時,我都會調用connect()。如果我有1000個客戶端,那麼我必須保留所有這些Channel對象,或者每次發送消息時創建一個新對象,這兩個對象看起來效率都不高。我的理解是正確的嗎? – wolfcastle
就是這樣。 –