为什么我发送的每个UDP消息的端口来源都在改变?

huangapple go评论69阅读模式
英文:

Why is my port source changing with every UDP message I send?

问题

我正在追踪我从我的Android手机发送的UDP消息在Wireshark上的情况,但每次发送消息时源端口号都会改变。

所以我有两个问题:

  1. 如果我想要接收回复消息,这样做是否不好?或者是否可以,只是每个接收到的消息通过不同的端口进来?

  2. 如果对问题1的回答是不好,那我应该怎么做才能改变这种情况?
    以下是我的代码:

编辑:完整代码

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    
    public static final int SERVERPORT = 1111;
    public static final String SERVER_IP = "255.255.255.255";
    
    private LinearLayout msgList;
    private EditText edMessage;
    private int clientTextColor;
    
    private ClientThread clientThread;
    private Thread thread;
    private Handler handler;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        msgList = findViewById(R.id.msgList);
        edMessage = findViewById(R.id.edMessage);
        clientTextColor = ContextCompat.getColor(this, R.color.colorAccent);
        handler = new Handler();
    }
    
    // 仅用于在设备上显示消息
    public TextView textView(String message, int color) {...}
    
    public void showMessage(final String message, final int color) {
        handler.post(new Runnable() {
            @Override
            public void run() {
                msgList.addView(textView(message, color));
            }
        });
    }
    
    // 实现部分
    
    @Override
    public void onClick(View view) {
    
        if(view.getId() == R.id.clear) {
            msgList.removeAllViews();
        }
    
        if (view.getId() == R.id.send_data) {
            // 启动线程
            clientThread = new ClientThread();
            thread = new Thread(clientThread);
            thread.start();
    
            String clientMessage = edMessage.getText().toString().trim(); // 客户端的消息
            showMessage(clientMessage, Color.BLUE); // 仅显示
            if (null != clientThread) {
                clientThread.sendMessage(clientMessage + "\r\n");
            }
        }
    }
    
    class ClientThread implements Runnable {
        byte[] buffer = new byte[1024];
    
        @Override
        public void run() {
            try {
                while (true) {
                    DatagramSocket ds = new DatagramSocket(SERVERPORT);
                    DatagramPacket dp = new DatagramPacket(buffer, buffer.length);
                    ds.receive(dp);
                    String serverMsg = new String(dp.getData(), 0, dp.getLength());
    
                    showMessage("Server: " + serverMsg, clientTextColor);
                    ds.close();
                }
            } catch (UnknownHostException e1) {
                e1.printStackTrace();
            }
        }
    
        void sendMessage(final String message) { // 被"Send Data"按钮调用
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        byte[] msg = message.getBytes();
                        InetAddress ip = InetAddress.getByName(SERVER_IP);
                        DatagramSocket socket = new DatagramSocket();
                        DatagramPacket packet = new DatagramPacket(msg, msg.length, ip, SERVERPORT);
                        socket.setBroadcast(true);
                        socket.send(packet);
                    } catch(Exception e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }
    }
    
    String getTime() {
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
        return sdf.format(new Date());
    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (null != clientThread) {
            clientThread.sendMessage("Disconnect");
            clientThread = null;
        }
    }
}
英文:

I'm tracking the UDP messages I'm sending from my android phone on Wireshark, but the source port number changes every time I send a message.

So I have two questions:

  1. Is this bad if I want to receive messages back? Or would it be find, just each received message comes through a different port?

  2. If the answer to 1) is yes it is bad, then what should I do to change that?
    Here's my code:

edit: Full code

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
public static final int SERVERPORT = 1111;
public static final String SERVER_IP = "255.255.255.255";
private LinearLayout msgList;
private EditText edMessage;
private int clientTextColor;
private ClientThread clientThread;
private Thread thread;
private Handler handler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
msgList = findViewById(R.id.msgList);
edMessage = findViewById(R.id.edMessage);
clientTextColor = ContextCompat.getColor(this, R.color.colorAccent);
handler = new Handler();
}
// Just for displaying messages on device 
public TextView textView(String message, int color) {...}
public void showMessage(final String message, final int color) {
handler.post(new Runnable() {
@Override
public void run() {
msgList.addView(textView(message, color));
}
});
}
// Implementation
@Override
public void onClick(View view) {
if(view.getId() == R.id.clear) {
msgList.removeAllViews();
}
if (view.getId() == R.id.send_data) {
// Starting thread
clientThread = new ClientThread();
thread = new Thread(clientThread);
thread.start();
String clientMessage = edMessage.getText().toString().trim(); // Client's Message
showMessage(clientMessage, Color.BLUE); // Just display
if (null != clientThread) {
clientThread.sendMessage(clientMessage + "\r\n");
}
}
}
class ClientThread implements Runnable {
byte[] buffer = new byte[1024];
@Override
public void run() {
try {
while (true) {
DatagramSocket ds = new DatagramSocket(SERVERPORT);
DatagramPacket dp = new DatagramPacket(buffer, buffer.length);
ds.receive(dp);
String serverMsg = new String(dp.getData(), 0, dp.getLength());
showMessage("Server: " + serverMsg, clientTextColor);
ds.close();
}
} catch (UnknownHostException e1) {
e1.printStackTrace();
}
}
void sendMessage(final String message) { // Called by "Send Data" button
new Thread(new Runnable() {
@Override
public void run() {
try {
byte[] msg = message.getBytes();
InetAddress ip = InetAddress.getByName(SERVER_IP);
DatagramSocket socket = new DatagramSocket();
DatagramPacket packet = new DatagramPacket(msg, msg.length, ip, SERVERPORT);
socket.setBroadcast(true);
socket.send(packet);
} catch(Exception e) {
e.printStackTrace();
}
}
}).start();
}
}
String getTime() {
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
return sdf.format(new Date());
}
@Override
protected void onDestroy() {
super.onDestroy();
if (null != clientThread) {
clientThread.sendMessage("Disconnect");
clientThread = null;
}
}
}

答案1

得分: 1

在你的代码中,每次迭代时都在创建一个新的套接字,这将会打开一个新的端口。这样多个客户端就可以与服务器并行通信。

  1. 大多数服务器会捕获你的IP地址和端口,这样它才能正确地响应你的套接字,但你必须确保你的套接字对象持续存在足够长的时间以进行观察。
  2. "坏"取决于目标。创建一个套接字,只要你需要与服务器通信,通过这个过程,使用这个套接字。你不需要打开另一个套接字,因为你正在初始化一个新的消息。
英文:

In your code you are creating a new socket with each iteration, which will open a new port. That's how multiple clients can communicate with a server in parallel.

  1. Most servers will capture your IP address and port, so it will respond correctly to your socket, but you have to make sure your socket object is persistent long enough to observe.
  2. Bad depends on the goal. Create a socket open as long as you need to communicate to the server, in that process, with that socket. You don't need to open another socket because you are initiating a new message.

huangapple
  • 本文由 发表于 2020年9月24日 03:09:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/64034769.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定