两个窗替发送一次就报错,说一个端口已经被绑定使用,如果一个窗口发,一个接就不会报错,怎么解决

 
 
```java
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.*;
 
public class TestFrame01 extends JFrame {
    JTextArea jta=new JTextArea();
  JTextField jtf=new JTextField(15);
 
    JPanel jp=new JPanel();
    JButton jb=new JButton("发送");
    DatagramSocket ds;
    DatagramPacket dp;
   String id;
   TestFrame01 tf=this;
    int port;
    public TestFrame01( String id,int port) throws IOException {
        this.port=port;
        this.id=id;
        init();
        operation();
        Receive();
    }
    public void init() throws UnknownHostException {
        this.setTitle("窗口1");
        this.setSize(500,500);
        jp.add(jtf);
        jp.add(jb);
        // 创建一个JScrollPane,并将JTextArea添加到其中
        JScrollPane scrollPane = new JScrollPane(jta);
        this.add(scrollPane, "Center");
        this.add(jp,"South");
 
 
        this.setDefaultCloseOperation(3);
        this.setAlwaysOnTop(true);
        this.setLocationRelativeTo(null);
        this.setVisible(true);
    }
 
    public  void operation() throws IOException {
 
        //发送给自己和另一个窗口
        jb.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (e.getSource() == jb) {
                    byte[] bytes = jtf.getText().trim().getBytes();
                    try {
                        ds = new DatagramSocket();
                        dp = new DatagramPacket(bytes, bytes.length, InetAddress.getByName(id), port);
                        ds.send(dp);
                        ds.close();
                    } catch (Exception ex) {
                        throw new RuntimeException(ex);
                    }
                    jta.setEditable(false);
                    jta.setFont(new Font("宋体", Font.BOLD, 25));
                    jta.setForeground(Color.red);
                    jta.append("我:" + jtf.getText().trim());
                    jta.append("\n");
                }
            }
        });
    }
    public void Receive(){
        try {
            jta.setEditable(false);
            jta.setFont(new Font("宋体", Font.BOLD, 25));
            jta.setEditable(false);
            while (true) {
                byte[] bytes = new byte[1024];
                ds = new DatagramSocket(10087);
                dp = new DatagramPacket(bytes, bytes.length);
                ds.receive(dp);
                String message = new String(dp.getData(), 0, dp.getLength());
                jta.append("窗口2发送了信息:" + message);
                jta.append("\n");
                ds.close();
            }
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }
    }
    public static void main(String[] args) throws IOException {
        new TestFrame01("127.0.0.1",10086);
    }
}
 
public class TestFrame02 extends JFrame{
    JTextArea jta=new JTextArea();
    JTextField jtf=new JTextField(15);
    JPanel jp=new JPanel();
    JButton jb=new JButton("发送");
    DatagramSocket ds;
    DatagramPacket dp;
    String sendID;
    int sendPORT;
    public TestFrame02( String sendID,int port) throws IOException {
        this.sendID=sendID;
        this.sendPORT=port;
        init();
        operation();
        Receive();
    }
 
    public void init() throws UnknownHostException {
        this.setTitle("窗口2");
        this.setSize(500,500);
 
        jp.add(jtf);
        jp.add(jb);
        // 创建一个JScrollPane,并将JTextArea添加到其中
        JScrollPane scrollPane = new JScrollPane(jta);
        this.add(scrollPane, "Center");
 
        this.add(jp,"South");
        this.setDefaultCloseOperation(3);
        this.setAlwaysOnTop(true);
        this.setLocationRelativeTo(null);
        this.setVisible(true);
    }
 
    public  void operation() throws IOException {
 
        //发送给自己和另一个窗口
        jb.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if(e.getSource()==jb){
                    byte[] bytes = jtf.getText().trim().getBytes();
                    try {
                        ds=new DatagramSocket();
                        dp=new DatagramPacket(bytes,bytes.length,InetAddress.getByName(sendID),sendPORT);
                        ds.send(dp);
                        ds.close();
                    }  catch (Exception ex) {
                        throw new RuntimeException(ex);
                    }
                    jta.setFont(new Font("宋体",Font.BOLD,25));
                    jta.setForeground(Color.red);
                    jta.append("我:"+jtf.getText().trim());
                    jta.append("\n");
                }
 
            }
        });
 
    }
 
    public void Receive(){
        jta.setFont(new Font("宋体",Font.BOLD,25));
        jta.setForeground(Color.red);
        jta.setEditable(false);
        while (true) {
            try {
                ds=new DatagramSocket(10086);
                byte[]bytes=new byte[1024];
                dp=new DatagramPacket(bytes,bytes.length);
                ds.receive(dp);
                String message=new String(dp.getData(),0,dp.getLength()) ;
 
                jta.append("窗口1发送了信息:"+message);
                jta.append("\n");
                ds.close();
            } catch (IOException ex) {
                throw new RuntimeException(ex);
            }
        }
    }
    public static void main(String[] args) throws IOException {
        new TestFrame02("127.0.0.1",10087);
    }
}
 
 
窗口1:ip本机 发送端口10086 接收端口10087     
窗口2:ip本机 发送端口10087 接收端口10086 
 
 

  • 帮你找了个相似的问题, 你可以看下: https://ask.csdn.net/questions/233459
  • 这篇博客你也可以参考下:为什么面试问源码,源码带给你的不仅仅是一份工作,更多的是这些
  • 除此之外, 这篇博客: 深入理解:为什么要使用工厂模式?中的 2.在工厂模式中,创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 如何理解这句话?
    即,在工厂模式中,每次创建任何类的一个实例对象时,并不需要对客户端直接暴露创建对象的具体逻辑,而是通过调用某一个共同接口,从而来返回一个该类新创建的对象。
    
    什么叫客户端?
    就是调用者。例如在a方法中调用b方法。a方法就可以称呼为“客户端”,b方法就是“服务端”
    
    什么叫共同接口?
    该共同接口一般就是工厂模式思想落地的一个类。该类可以为每个不同对象分别对外暴露一个调用方法(也可以叫调用接口)
    
  • 您还可以看一下 韦语洋(Lccee)老师的一机一码加密、被破解自动销毁随时授权回收升级系列视频课程课程中的 演示误报效果,一些被误报的特征的解除方式(重要)小节, 巩固相关知识点
  • 以下回答由chatgpt基于相关博客总结生成:

    如何解决同时在两个窗口发送信息时出现端口绑定使用错误的问题?

    当同时发送信息到两个窗口时,会出现端口已经被绑定使用的错误。这是因为同一个端口在TCP/IP协议中只能被一个进程或者应用程序绑定。为了解决这个问题,可以通过以下几个步骤来实现:

    1. 使用不同的端口号:在两个窗口中,将端口号分别设置为不同的数值。这样可以避免两个窗口尝试绑定同一个端口号的情况。可以根据具体情况在代码中设置不同的端口号。
    # 窗口1
    port1 = 8000
    # 窗口2
    port2 = 9000
    
    1. 使用不同的IP地址:如果两个窗口在同一台机器上运行,可以使用不同的IP地址来区分。可以将一个窗口绑定到本地回环地址(127.0.0.1),将另一个窗口绑定到机器的实际IP地址。
    # 窗口1绑定到本地回环地址
    host1 = '127.0.0.1'
    # 窗口2绑定到实际IP地址
    host2 = '192.168.0.100'
    
    1. 端口复用(Port Reuse):在一些操作系统上,可以设置端口复用,允许多个进程或应用程序绑定到同一个端口。这样可以避免端口被占用的错误。在Python中,可以使用SO_REUSEADDR选项来开启端口复用。
    import socket
    
    # 创建socket对象
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    
    # 开启端口复用
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    
    # 绑定端口和地址
    sock.bind(('127.0.0.1', 8000))
    
    # 监听连接
    sock.listen(5)
    

    如果以上方法都不能解决问题,那可能是操作系统级别的限制或者其他原因导致无法同时在两个窗口绑定相同的端口。这种情况下,可以考虑使用不同的网络协议或者使用消息队列等方式来实现两个窗口之间的通信。

img