UDP/TCP サーバーとクライアントを使ったゲームがあります。クライアントの位置を更新するための 1 つの UDP ポート (2406) と、チャット用の 1 つの TCP ポート (2407)。ここでの問題は 2406 にあります。
ローカル ネットワークでクライアントを再生すると、すべて正常に動作します。しかし、外部クライアントが参加したい場合、最初のパッケージ (参加コマンド) しか受信せず、その後は... 何も受信しません。私 (ローカル ネットワークにログインしている) には、外部プレーヤーが表示されません。しかし、彼らは私を見ることができます。チャットは双方で機能します。したがって、これは実際には DatagramSocket に関連しています。TCP ではなく UDP に関連する情報をできるだけ多く投稿するようにします。
ここで何が問題なのか誰でも知っていますか?
ポートは UDP 2406、TCP 2407 のように転送されます。
サーバー、ソケット:
DatagramSocket socket = new DatagramSocket(2406, InetAddress.getLocalHost());
ServerSocket serversocket_chat = new ServerSocket(2407, 0, InetAddress.getLocalHost());
サーバー、受信スレッド:
byte[] buffer = new byte[1024];
DatagramPacket dp = new DatagramPacket(buffer, 1024);
while(true){
try{
this.socket.receive(dp);
String data = new String(dp.getData(), 0, dp.getLength()).trim();
String[] args = data.split(":");
String command = args[0];
String reply = null;
try{
reply = handleCommand(dp, command, args);
} catch( Exception e ){
System.err.println("Error while handling command: " + command);
e.printStackTrace();
}
if(reply != null){
reply += "\n";
DatagramPacket reply_packet = new DatagramPacket(reply.getBytes(), reply.length(), dp.getSocketAddress());
this.socket.send(reply_packet);
}
} catch (IOException e){
e.printStackTrace();
}
}
new Thread(chat_receive).start();
誰かがメッセージを送信するとすぐに、メソッド handleCommand がそれが何であるかを調べます。すべてのメッセージは、String から派生した byte[] です。メッセージが「cj:Hello」の場合、handleCommand はコマンド cs、ユーザー名 Hello を見つけます。これはサーバーによって受信されます。その後、同じ人が何かを送信しても、何も受信されません。
クライアント ソケット:
private DatagramSocket socket;
private Socket socket_chat;
クライアント接続:
this.socket = new DatagramSocket();
this.socket_chat = new Socket(ip, port+1);
クライアント送信:
private Runnable send = new Runnable() {
@Override
public void run() {
DatagramPacket dp;
String sendStringBuffered;
while(true){
if(sendString != null){
sendStringBuffered = sendString;
dp = new DatagramPacket(sendStringBuffered.getBytes(), sendStringBuffered.length(), ip, port);
try {
socket.send(dp);
} catch (IOException ex) {
Logger.getLogger(NewClient.class.getName()).log(Level.SEVERE, null, ex);
}
sendString = null;
}
}
}
};