Java 使SocketServer保持活动状态,直到框架关闭
我试图实现的是,使用我的程序,用户可以随时上传文件,当他们单击“关闭”按钮时,我想关闭或终止套接字连接,但当我再次运行GUI时,连接仍然存在,即使我还没有启动它Java 使SocketServer保持活动状态,直到框架关闭,java,sockets,Java,Sockets,我试图实现的是,使用我的程序,用户可以随时上传文件,当他们单击“关闭”按钮时,我想关闭或终止套接字连接,但当我再次运行GUI时,连接仍然存在,即使我还没有启动它 while (true) { // >>>>>>>HERE IS MY PROBLEM<<<<<<< try{ connectionSocket = welcomeSocket.accept(); inFromClient =
while (true) { // >>>>>>>HERE IS MY PROBLEM<<<<<<<
try{
connectionSocket = welcomeSocket.accept();
inFromClient = new BufferedReader(new InputStreamReader(
connectionSocket.getInputStream()));
outToClient = new DataOutputStream(
connectionSocket.getOutputStream());
//Do something here.....
}catch(IOException e){ }
}
你有几个选择 在套接字循环中创建一个可以从外部触发的“转义”标志(例如,设置为false)。在框架中添加一个
WindowListener
,然后在windowClosing
上翻转标志并中断线程。这将允许循环终止
您也可以尝试在守护进程线程中设置服务器套接字,但我怀疑这不会起作用,因为服务器套接字的阻塞操作可能不会在意
用示例更新
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestSocket {
private SocketThread socketThread;
public static void main(String[] args) {
new TestSocket();
}
public TestSocket() {
socketThread = new SocketThread();
socketThread.start();
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridBagLayout());
frame.add(new JLabel("Close me if you dare"));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
socketThread.stopThatSocket();
}
});
}
});
}
public class SocketThread extends Thread {
private volatile boolean flagToSetWhenYouWantToStop = true;
private ServerSocket socket = null;
public SocketThread() {
setName("Socket");
setDaemon(true);
}
public void stopThatSocket() {
flagToSetWhenYouWantToStop = false;
if (socket != null) {
try {
socket.close();
} catch (IOException ex) {
}
}
interrupt();
try {
join();
} catch (InterruptedException ex) {
}
}
@Override
public void run() {
try {
socket = new ServerSocket(1234);
while (flagToSetWhenYouWantToStop) {
Socket accept = socket.accept();
}
} catch (IOException exp) {
exp.printStackTrace();
}
}
}
}
使用简单套接字命令示例更新
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestSocket {
private SocketThread socketThread;
public static void main(String[] args) {
new TestSocket();
}
public TestSocket() {
socketThread = new SocketThread();
socketThread.start();
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridBagLayout());
frame.add(new JLabel("Close me if you dare"));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
socketThread.stopThatSocket();
}
});
}
});
}
public class SocketThread extends Thread {
private volatile boolean flagToSetWhenYouWantToStop = true;
private ServerSocket socket = null;
public SocketThread() {
setName("Socket");
setDaemon(true);
}
public void stopThatSocket() {
flagToSetWhenYouWantToStop = false;
if (socket != null) {
try {
socket.close();
} catch (IOException ex) {
}
}
interrupt();
try {
join();
} catch (InterruptedException ex) {
}
}
@Override
public void run() {
try {
socket = new ServerSocket(1234);
while (flagToSetWhenYouWantToStop) {
Socket accept = socket.accept();
}
} catch (IOException exp) {
exp.printStackTrace();
}
}
}
}
此示例basic通过套接字进行通信,告诉服务器它应该关闭
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.net.SocketFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestSocket {
private SocketThread socketThread;
public static void main(String[] args) {
new TestSocket();
}
public TestSocket() {
socketThread = new SocketThread();
socketThread.start();
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridBagLayout());
frame.add(new JLabel("Close me if you dare"));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
// socketThread.stopThatSocket();
Socket socket = null;
try {
socket = SocketFactory.getDefault().createSocket("localhost", 1234);
BufferedWriter bw = null;
try {
bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
System.out.println("Out-Cmd = STOP");
bw.write("stop");
bw.newLine();
} finally {
try {
bw.close();
} catch (Exception exp) {
}
}
} catch (IOException ex) {
ex.printStackTrace();
} finally {
try {
socket.close();
} catch (Exception exp) {
}
}
}
});
}
});
}
public class SocketThread extends Thread {
private volatile boolean flagToSetWhenYouWantToStop = true;
private ServerSocket socket = null;
public SocketThread() {
setName("Socket");
setDaemon(true);
}
public void stopThatSocket() {
flagToSetWhenYouWantToStop = false;
if (socket != null) {
try {
socket.close();
} catch (IOException ex) {
}
}
interrupt();
try {
join();
} catch (InterruptedException ex) {
}
}
@Override
public void run() {
try {
socket = new ServerSocket(1234);
while (flagToSetWhenYouWantToStop) {
Socket accept = socket.accept();
/**
* Normally I would have a command processor take care of this,
* read in the command and then terminate the server thread by
* calling stopThatSocket...
*/
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(accept.getInputStream()));
String cmd = br.readLine();
System.out.println("In-Cmd = " + cmd);
if (cmd.equalsIgnoreCase("stop")) {
stopThatSocket();
}
} finally {
try {
br.close();
} catch (Exception e) {
}
}
}
} catch (IOException exp) {
exp.printStackTrace();
}
}
}
}
我对Java非常陌生,对这方面的信息并不多。这是我正在使用的两个文件,我怎样才能发送一些东西来触发while循环?@Ali是认真的吗?您是Java新手,已经在玩套接字了,但不知道如何退出简单的
while循环。尝试新事物的要点,但也许你需要先掌握基本知识。。。IMHOno,我的意思是,我不知道如何将布尔值从客户端发送到服务器以触发while循环。很抱歉没有澄清我的陈述。我认为您的示例非常好且清晰,但正如我提到的,我有两个文件,一个是Client.java,另一个是Server.java。当Client.java调用GUI并关闭它时,我希望将布尔值传递给Server.java以触发while循环。我可以这样做吗?我添加了另一个简单的示例。它启动一个本地服务器套接字。当您关闭窗口时,将创建一个新的套接字,该套接字向服务器套接字发送“stop”命令,然后关闭。然后,服务器端的“stop”命令会导致调用stopThatSocket
方法