客户端-服务器 - 冻结按钮
Client-Server - freezing button
我正在编写一个简单的客户端-服务器应用程序。它应该像那样工作。我 运行 服务器应用程序比我单击按钮创建服务器。当服务器打开时,我可以使用客户端应用程序并连接到服务器。服务器也有 JTextFild tfLog,其中弹出消息日志。
我的问题是当我单击按钮创建服务器时如果冻结。
Image
一切看起来像这样:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class ServerGui extends JFrame implements ActionListener{
protected JButton bCreateServer;
public static JTextArea taLOg;
public ServerGui(){
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
dispose();
}
});
initLayout();
setVisible(true);
}
private void initLayout() {
setSize(600, 400);
setResizable(false);
setLayout(null);
Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize();
this.setLocation(dimension.width/2-this.getSize().width/2,
dimension.height/2 - this.getSize().height/2);
bCreateServer = new JButton("Utwórz serwer");
bCreateServer.setBounds(20,20,150,25);
bCreateServer.addActionListener(this);
bCreateServer.setActionCommand("Create");
add(bCreateServer);
taLOg = new JTextArea();
taLOg.setEditable(false);
JScrollPane pane = new JScrollPane(taLOg);
pane.setBounds(20, 50, 400,300);
add(pane);
}
public static void main(String args[]){
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new ServerGui();
}
});
}
public void insertText(final String line){
if(SwingUtilities.isEventDispatchThread()){
taLOg.insert(line, 0);
}
else{
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run(){
taLOg.insert(line, 0);
}
});
}
}
@Override
public void actionPerformed(ActionEvent e) {
String tmp = e.getActionCommand();
if(tmp.equals("Create")){
Server server = new Server(8080);
if(server.serverCreated){
insertText("Kliknięto Utwórz serwer\n");
server.clientsListener();
}
else{
insertText("Nie udało się utworzyć serwera\n");
}
}
}
}
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server{
private ServerSocket serverSocket;
private Socket socket;
public Boolean serverCreated = false;
public Server(int port){
try{
serverSocket = new ServerSocket(port);
}
catch(IOException e){
System.out.println("Błąd przy tworzeniu gniazda serwerowego.");
System.exit(-1);
}
serverCreated = true;
}
public void clientsListener(){
try{
socket = serverSocket.accept();
}
catch(IOException e){
System.out.println(e);
}
System.out.println(socket);
try{
serverSocket.close();
}
catch(IOException e){
System.out.println("Błąd przy zamykaniu gniazda serwerowego.");
System.exit(-1);
}
}
}
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client{
Socket clientSocket;
public Client(String hostname, int port){
try{
clientSocket = new Socket(hostname, port);
}
catch(UnknownHostException e){
System.out.println("Nieznany host.");
}
catch(IOException e){
System.out.println(e);
System.exit(-1);
}
System.out.println(clientSocket);
}
public static void main(String args[]){
Client client = new Client("localhost", 8080);
}
}
您的 actionPerformed 处理程序(在应用程序的主 UI 线程上执行)调用服务器对象上的 clientsListen(),然后调用 .accept()。 accept() 将阻塞直到客户端连接。这就是为什么你的GUI挂了。
您需要创建一个新线程来为您的服务器执行代码。
actionPerformed 中的类似内容:
Thread t = new Thread(new Runnable() {
@Override
public void run() {
Server server = new Server(8080);
if(server.serverCreated){
server.clientsListener();
}
}
});
t.setDaemon(true);
t.start();
让客户端启动服务器也有点奇怪。作为一个实验,我可以理解它,但如果你给客户端启动服务器的能力,你应该给他们一个停止它的方法。这将涉及线程之间的某种 IPC,这可能会偏离您的简单概念。
我正在编写一个简单的客户端-服务器应用程序。它应该像那样工作。我 运行 服务器应用程序比我单击按钮创建服务器。当服务器打开时,我可以使用客户端应用程序并连接到服务器。服务器也有 JTextFild tfLog,其中弹出消息日志。 我的问题是当我单击按钮创建服务器时如果冻结。 Image
一切看起来像这样:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class ServerGui extends JFrame implements ActionListener{
protected JButton bCreateServer;
public static JTextArea taLOg;
public ServerGui(){
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
dispose();
}
});
initLayout();
setVisible(true);
}
private void initLayout() {
setSize(600, 400);
setResizable(false);
setLayout(null);
Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize();
this.setLocation(dimension.width/2-this.getSize().width/2,
dimension.height/2 - this.getSize().height/2);
bCreateServer = new JButton("Utwórz serwer");
bCreateServer.setBounds(20,20,150,25);
bCreateServer.addActionListener(this);
bCreateServer.setActionCommand("Create");
add(bCreateServer);
taLOg = new JTextArea();
taLOg.setEditable(false);
JScrollPane pane = new JScrollPane(taLOg);
pane.setBounds(20, 50, 400,300);
add(pane);
}
public static void main(String args[]){
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new ServerGui();
}
});
}
public void insertText(final String line){
if(SwingUtilities.isEventDispatchThread()){
taLOg.insert(line, 0);
}
else{
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run(){
taLOg.insert(line, 0);
}
});
}
}
@Override
public void actionPerformed(ActionEvent e) {
String tmp = e.getActionCommand();
if(tmp.equals("Create")){
Server server = new Server(8080);
if(server.serverCreated){
insertText("Kliknięto Utwórz serwer\n");
server.clientsListener();
}
else{
insertText("Nie udało się utworzyć serwera\n");
}
}
}
}
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server{
private ServerSocket serverSocket;
private Socket socket;
public Boolean serverCreated = false;
public Server(int port){
try{
serverSocket = new ServerSocket(port);
}
catch(IOException e){
System.out.println("Błąd przy tworzeniu gniazda serwerowego.");
System.exit(-1);
}
serverCreated = true;
}
public void clientsListener(){
try{
socket = serverSocket.accept();
}
catch(IOException e){
System.out.println(e);
}
System.out.println(socket);
try{
serverSocket.close();
}
catch(IOException e){
System.out.println("Błąd przy zamykaniu gniazda serwerowego.");
System.exit(-1);
}
}
}
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client{
Socket clientSocket;
public Client(String hostname, int port){
try{
clientSocket = new Socket(hostname, port);
}
catch(UnknownHostException e){
System.out.println("Nieznany host.");
}
catch(IOException e){
System.out.println(e);
System.exit(-1);
}
System.out.println(clientSocket);
}
public static void main(String args[]){
Client client = new Client("localhost", 8080);
}
}
您的 actionPerformed 处理程序(在应用程序的主 UI 线程上执行)调用服务器对象上的 clientsListen(),然后调用 .accept()。 accept() 将阻塞直到客户端连接。这就是为什么你的GUI挂了。
您需要创建一个新线程来为您的服务器执行代码。
actionPerformed 中的类似内容:
Thread t = new Thread(new Runnable() {
@Override
public void run() {
Server server = new Server(8080);
if(server.serverCreated){
server.clientsListener();
}
}
});
t.setDaemon(true);
t.start();
让客户端启动服务器也有点奇怪。作为一个实验,我可以理解它,但如果你给客户端启动服务器的能力,你应该给他们一个停止它的方法。这将涉及线程之间的某种 IPC,这可能会偏离您的简单概念。