使用UDP服务器 - 客户机在同一端口上同时客户机、端口、服务器、在同一

2023-09-07 09:38:10 作者:死于心海、葬于脑海

我有一个应用程序,它使用UDP数据包的工作。所以我想送,并在同一时间,同一应用程序接收UDP数据包。是真的吗?现在它完美,而是分开。 code代码片段: UDP服务器:

I have an app which works with UDP packets. So I want to send and receive UDP packets at the same time in the same app. Is it real? Now it works perfectly, but separately. Code snippet: UDP Server:

public class UDPServer {    
DatagramPacket packet;  
DatagramSocket socket;      
static int port = 11111;    
private boolean isRun = false;
private String message = "";
private int broadcastInterval;  
private Context context;

public boolean IsRunUDPServer(){
    return isRun;
}
public void StopBroadcasting(){
    isRun = false;      
}
public void StartBroadcasting(String message, int broadcastInterval){
    isRun = true;
    this.message = message;
    this.broadcastInterval = broadcastInterval;     
    new Thread(runner).start();     
}

Runnable runner = new Runnable() {      
    public void run() {
        while(isRun){               
            try {
                //Sending(message);
                SendBroadcastMessageOverWiFi(message);
                Thread.sleep(broadcastInterval);
                Log.e("SendBroadcastMessageOverWiFi", message);
            } catch (InterruptedException e) {                  
                e.printStackTrace();
            } catch (IOException e) {                   
            }
        }
        if(socket!=null){
            socket.disconnect();
            socket.close();             
        }           
    }
};

public UDPServer(Context context) {
    this.context=context;       
}

private InetAddress getBroadcastAddress() throws IOException {      
    WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
    DhcpInfo dhcp = wifi.getDhcpInfo();
    // handle null somehow
    if(dhcp==null){ return null; }
    int broadcast = (dhcp.ipAddress & dhcp.netmask) | ~dhcp.netmask;
    byte[] quads = new byte[4];
    for (int k = 0; k < 4; k++)
      quads[k] = (byte) ((broadcast >> k * 8) & 0xFF);
    return InetAddress.getByAddress(quads);
}

private void SendBroadcastMessageOverWiFi(String message) throws IOException{
    InetAddress addr = getBroadcastAddress();
    if(addr!=null){
        if(socket==null){
            socket = new DatagramSocket(port);          
            socket.setBroadcast(true);              
        }
        DatagramPacket packet = new DatagramPacket(message.getBytes(), message.getBytes().length,
            addr, port);
        socket.send(packet);                
    }       
}}

UDP客户端:

public class UDPClient {
MulticastSocket socket;
InetAddress groupAddress;
DatagramPacket packet;
byte[] buffer;

private static final int UDP_SERVER_PORT = 11111;
private static final int MAX_UDP_DATAGRAM_LEN = 32768;      

public interface OnReceiveDataListener{
    public abstract void onReceiveData(String data);
}

private OnReceiveDataListener ReceiveDataListener = null;   

public void setReceiveDataListener(OnReceiveDataListener ReceiveDataListener) {
    this.ReceiveDataListener = ReceiveDataListener;
}

public OnReceiveDataListener getReceiveDataListener() {
    return ReceiveDataListener;
}

private boolean isRun = false;  
private Thread broadcastReceiver;
public void StopReceiving(){
    isRun = false;      
}
public void StartReceiving(){
    isRun = true;           
    buffer = new byte[4096];
    broadcastReceiver = new Thread(runner);     
    broadcastReceiver.start();
}
Runnable runner = new Runnable() {      
    @Override
    public void run() {
        while(isRun){               

            String lText;
            packet = new DatagramPacket(buffer, buffer.length);             
            DatagramSocket ds = null;
            try {
                ds = new DatagramSocket(UDP_SERVER_PORT);                   
                ds.receive(packet);
                lText = new String(packet.getData(), 0, packet.getLength());
                Log.i("UDP packet received", lText+"  "+packet.getLength()+"  "+packet.getData().length);
                if(getReceiveDataListener()!=null)
                    getReceiveDataListener().onReceiveData(lText);

            } catch (SocketException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (ds != null) {
                    ds.close();
                }
            }
        }           
    }
};}

如果我启动服务器,客户端将无法接收UDP数据包。 请帮我。谢谢你。

If I start server, the client won't be able receive udp packets. Please help me. Thank you.

推荐答案

只有一个插座(一个过程)可以绑定到一个给定的UDP端口在同一时间。它不允许有两个插座绑定到相同的UDP端口号。

Only one socket (in one process) can bind to a given UDP port at one time. It is not permitted to have two sockets bind to the same UDP port number.

在大多数情况下,没有理由要绑定到一个特定端口的客户端。相反,指定端口 0 INADDR_ANY ),系统将分配一个未使用的动态端口。

In most cases, there is no reason to have the client bound to a specific port. Instead, specify port 0 (INADDR_ANY) and the system will assign an unused dynamic port.