Java socket

在jframe中使用JTextField输入ip地址,

img

点击连接按钮通过点击事件 声明socket并与server建立连接

 btnconnect.addActionListener(new ActionListener(){   
            public void actionPerformed(ActionEvent e){
                SocketConnect sc= new SocketConnect(txtip.getText());
                
            }
        });
public class SocketConnect implements Runnable{

    Socket socket;
    String ip;
    SocketConnect(String ip){
        this.ip=ip;
    }
    
    @Override
    public void run() {
        // TODO Auto-generated method stub
        try {
            socket = new Socket(ip,502);
        } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        
    }

}

建立连接后,点击开始监控按钮开始向server端发送数据
问题1:socket是在连接按钮的点击事件里面声明的无法传到开始监控按钮的点击事件里面,希望达到的效果就是点击连接按钮就建立一个新的socket,所以不能使用静态变量,如何将连接按钮里面的socket对象传给开始监控按钮的点击事件里面的线程。
问题2:另外如何判断是否已经与该ip的server建立了连接,如果已经建立了连接就system.out.print一句话,如果没建立连接再建立socket,麻烦哪个牛人给解决下

基于Monster 组和GPT的调写:
问题1:可以将socket对象作为参数传递给开始监控按钮的点击事件里面的线程。例如,可以在SocketConnect类中添加一个方法,该方法接受一个socket参数,并将其设置为该类的实例变量。然后,可以在连接按钮的点击事件中创建SocketConnect对象,并将其传递给开始监控按钮的点击事件。

例如:

public class SocketConnect implements Runnable{

    private Socket socket;
    private String ip;
    
    public void setSocket(Socket socket) {
        this.socket = socket;
    }

    SocketConnect(String ip){
        this.ip=ip;
    }
    
    @Override
    public void run() {
        // TODO Auto-generated method stub
        try {
            if (socket == null || socket.isClosed()) {
                socket = new Socket(ip,502);
            }
        } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}


然后,在连接按钮的点击事件中,您可以创建一个新的SocketConnect对象,并将其传递给开始监控按钮的点击事件。例如:

Socket socket = null;
btnconnect.addActionListener(new ActionListener(){   
    public void actionPerformed(ActionEvent e){
        if (socket == null || socket.isClosed()) {
            socket = new Socket();
            SocketConnect sc= new SocketConnect(txtip.getText());
            sc.setSocket(socket);
            Thread thread = new Thread(sc);
            thread.start();
        }
    }
});

btnstart.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        if (socket != null && socket.isConnected()) {
            // 在此处发送数据
        }
    }
});


问题2:可以在SocketConnect类中添加一个方法来检查socket是否已经连接到服务器。例如:

public boolean isConnected() {
    return socket != null && socket.isConnected() && !socket.isClosed();
}



``
然后,在连接按钮的点击事件和开始监控按钮的点击事件中都可以调用该方法来检查socket是否已连接到服务器。例如:

btnconnect.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
if (socket == null || !sc.isConnected()) {
socket = new Socket();
SocketConnect sc= new SocketConnect(txtip.getText());
sc.setSocket(socket);
Thread thread = new Thread(sc);
thread.start();
} else {
System.out.println("已连接到服务器。");
}
}
});

btnstart.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (socket != null && sc.isConnected()) {
// 在此处发送数据
} else {
System.out.println("未连接到服务器。");
}
}
});

```

该回答引用GPTᴼᴾᴱᴺᴬᴵ
问题1:可以将socket对象声明为JFrame类的成员变量,这样就可以在两个按钮的点击事件中都访问到了,例如:

public class MyFrame extends JFrame{
    private Socket socket;
    private JTextField txtip;
    //...
    
    public MyFrame(){
        //...
        JButton btnconnect = new JButton("连接");
        btnconnect.addActionListener(new ActionListener(){   
            public void actionPerformed(ActionEvent e){
                connectToServer(txtip.getText());
            }
        });
        
        JButton btnstart = new JButton("开始监控");
        btnstart.addActionListener(new ActionListener(){   
            public void actionPerformed(ActionEvent e){
                sendDataToServer();
            }
        });
    }
    
    private void connectToServer(String ip){
        if(socket != null && socket.isConnected()){
            System.out.println("已经与该IP的Server建立了连接");
            return;
        }
        try {
            socket = new Socket(ip,502);
            System.out.println("已经与该IP的Server建立了连接");
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    private void sendDataToServer(){
        if(socket == null || !socket.isConnected()){
            System.out.println("还未与该IP的Server建立连接,请先连接");
            return;
        }
        //开始发送数据
    }
}


问题2:在connectToServer方法中,通过socket对象的isConnected方法判断是否已经与Server建立了连接,如果已经连接则直接返回,否则建立连接。

参考gpt和自己的思路,问题1:要将连接按钮中的socket对象传递到开始监控按钮的点击事件中,可以在连接按钮的点击事件中创建一个新的SocketConnect对象,将其作为参数传递给开始监控按钮的点击事件。具体实现如下:


// 声明一个 SocketConnect 对象,在连接按钮点击事件中初始化
SocketConnect sc;

// 连接按钮点击事件中
btnconnect.addActionListener(new ActionListener(){   
    public void actionPerformed(ActionEvent e){
        // 创建新的 SocketConnect 对象,并传递 ip 地址
        sc = new SocketConnect(txtip.getText());
    }
});

// 开始监控按钮点击事件中,使用连接按钮中创建的 SocketConnect 对象
btnstart.addActionListener(new ActionListener(){
    public void actionPerformed(ActionEvent e){
        // 判断是否已经建立连接
        if (sc == null || sc.socket == null || sc.socket.isClosed()) {
            // 如果未建立连接,提示用户建立连接
            System.out.println("请先建立连接");
        } else {
            // 如果已建立连接,执行发送数据的逻辑
            new Thread(new SendThread(sc.socket)).start();
        }
    }
});


在上述代码中,我们在连接按钮的点击事件中创建了一个新的 SocketConnect 对象,并将其赋值给一个名为 sc 的成员变量。在开始监控按钮的点击事件中,我们通过判断 sc 变量的值,来确定是否已经建立连接。如果 sc 为 null,或者 sc 中的 socket 对象为 null,或者 socket 已经关闭,那么就认为尚未建立连接,提示用户建立连接。否则,就启动一个新的线程,执行发送数据的逻辑。

问题2:要判断是否已经与该 IP 的 server 建立了连接,可以在 SocketConnect 类中添加一个 isConnect() 方法。具体实现如下:


public class SocketConnect implements Runnable{
    Socket socket;
    String ip;
    SocketConnect(String ip){
        this.ip=ip;
    }
    @Override
    public void run() {
        // TODO Auto-generated method stub
        try {
            socket = new Socket(ip,502);
        } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    
    public boolean isConnect() {
        return socket != null && socket.isConnected() && !socket.isClosed();
    }
}


在上述代码中,我们添加了一个 isConnect() 方法,该方法返回一个 boolean 值,用于表示当前 SocketConnect 对象是否已经与指定的 IP 的 server 建立了连接。具体实现中,我们通过判断 socket 是否为 null,以及是否已经连接和是否已经关闭来确定连接状态。如果返回 true,说明已经建立连接;否则说明尚未建立连接。

然后,在开始监控按钮的点击事件中,可以调用 SocketConnect 对象的 isConnect() 方法来判断是否已经建立连接。具体实现参见问题1的代码。

问题一可以使用数组,定义在方法外

望采纳。
https://blog.csdn.net/weixin_44804207/article/details/125746710