0

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;
            }
        }
    }
};
4

1 に答える 1

0

次の 2 つのことが考えられます。

  • UDP は信頼できません。データグラムはいつでも失われる可能性があります
  • UDP パケットは通常、そのように NAT を通過しません。

体系的なトラブルシューティングのために、パケット スニファー/アナライザー (tcpdump や wireshark など) を使用して、パケットが実際に宛先に到達することを確認します。

于 2012-10-02T17:58:09.350 に答える