Java - 线程,Swing和ServerSocket [英] Java - Threads, Swing, and ServerSocket

查看:155
本文介绍了Java - 线程,Swing和ServerSocket的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道我知道,已经有一百万的问题和答案这无处不在。吨的真正详细的文章,几种类型的例子。我花了过去几个小时阅读它,但这不是做的伎俩。我问这个的原因是因为我仍然不安静了解我需要做的显然是因为我的代码仍然不工作。我得到了如何Swing与EDT的工作原理,如果我要使用ServerSocket的accept()方法,我需要为Swing启动一个新的线程(我想?)。当我运行我的代码,因为它是窗口只是打开和冻结。 我的问题是,有人可能看我的代码,告诉我我做错了,并解释它,我只有一半的大脑? (因为这就是我的感觉。 :P)



以下是我已阅读的一些地方:





Main.class

  package com.sever.core; 

import java.io.IOException;
import java.net.Socket;
import java.util.Scanner;

import javax.swing.SwingUtilities;

public class Main {

private SocketManager network;
public static void main(String [] args){

SwingUtilities.invokeLater(new Runnable(){
@Override
public void run(){
Window window = new Window();
window.setVisible(true);
}
});

SwingUtilities.invokeLater(new Runnable(){
@Override
public void run(){
Main main = new Main();
main .run();
}
});


}

public void run(){
network = new SocketManager(25595);

while(true){
try {
network.setSocket(network.getServerSocket()。accept());
AddUser(network.getSocket());
线程x =新线程(网络);
x.start();
} catch(Exception e){
System.out.println(无法连接。
}
}

}

public void AddUser(Socket s){
try {
Scanner input = new Scanner (s.getInputStream());
network.addUser(input.nextLine());
} catch(Exception e){

}
}
}

Window.class

  package com.sever.core; 

import java.awt。*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing。*;

public class Window extends JFrame {

private int screenWidth = 800;
private int screenHeight = 600;
private线程;

private JPanel window = new JPanel();
private JTextArea consle = new JTextArea(Server started ....);
private JTextField input = new JTextField();
private JScrollPane consleinput = new JScrollPane(consle);

public Window(){
this.setName(NAMEHERE - Server Software);
setResizable(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(screenWidth,screenHeight);
window.setBackground(Color.DARK_GRAY);
window.setLayout(new BoxLayout(window,BoxLayout.Y_AXIS));

consleSetup();
addComponets();
}

private void addComponets(){
add(window);
window.add(consleinput);
window.add(input);
}

private void consleSetup(){
consle.setEditable(false);
consle.setLineWrap(true);
consle.setBorder(BorderFactory.createEmptyBorder(3,3,3,3));
consleinput.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_​​ALWAYS);
input.setMaximumSize(new Dimension(Integer.MAX_VALUE,input.getPreferredSize()。height));
}

private void addListeners(){
input.addActionListener(new ActLis());
input.setActionCommand(input);
}

}

.class

  package com.sever.core; 

import java.io. *;
import java.net。*;
import java.util.ArrayList;

public class SocketManager implements Runnable {

private Socket sock;
private ServerSocket sersoc;
private PrintWriter输出;
private BufferedReader输入;
private线程;

public ArrayList< Socket> currentConnections = new ArrayList< Socket>();
public ArrayList< String> currentUsers = new ArrayList< String>();


public SocketManager(String ip,int port){
try {
sock = new Socket(ip,port);
PrintWriter output = new PrintWriter(sock.getOutputStream());
BufferedReader input = new BufferedReader(
new InputStreamReader(sock.getInputStream()));
System.out.println(Server:socket started。);
} catch(Exception e){
System.out.println(Server:Socket failed to connect.\\\
);
}
}

public SocketManager(int port){
try {
sersoc = new ServerSocket(port);

} catch(IOException e){
System.out.println(Server:Socket failed to connect.\\\
);
}
}

public SocketManager(Socket socket){
this.sock = socket;

try {
output = new PrintWriter(sock.getOutputStream());
input = new BufferedReader(
new InputStreamReader(sock.getInputStream()));
} catch(Exception e){

}
}

public synchronized void checkConnetion(){
if(!sock.isConnected ()){
for(int x = 0; x <= currentConnections.size(); x ++){
if(currentConnections.get(x)== sock){
currentConnections .remove(x);
System.out.println(Server:Disconnecting from:+ currentConnections.get(x)+\\\
);
}
}
}
}

public synchronized Socket getSocket(){
return sock;
}

public synchronized ServerSocket getServerSocket(){
return sersoc;
}

public synchronized void setSocket(Socket s){
System.out.println(Setting socket to:+ s.getInetAddress());
sock = s;
}

public synchronized void addSocket(Socket s){
currentConnections.add(s);
}

public synchronized void addUser(String u){
currentUsers.add(u);
}

public synchronized ArrayList< Socket> getConnections(){
return currentConnections;
}

public synchronized ArrayList< String> getUsers(){
return currentUsers;
}

public synchronized void send(String data){
try {
output.println(data);
} catch(Exception e){

}
}

public synchronized void close(){
try {
sock.close();
} catch(Exception e){

}
output = null;
input = null;
System.gc();
}

public synchronized boolean isConnected(){
return(sock == null)? false:(sock.isConnected()&&!sock.isClosed());
}

@Override
public void run(){
System.out.println(Is runing。
while(true){
try {
checkConnetion();
if(input.readLine()。isEmpty()){
return;
}

output.println(Server:Recived your message。);
} catch(Exception e){

} finally {
try {
sock.close();
} catch(Exception e){

}
}
}

}

}

ActLis.class
$ b

  package com.sever.core; 

import java.awt.event。*;
import javax.swing。*;

public class ActLis implements ActionListener {

private JTextField actionField;
public ActLis(){

}

public ActLis(JTextField t){
actionField = t;
}

@Override
public void actionPerformed(ActionEvent e){
// TODO自动生成方法存根
String cmd = e.getActionCommand );

if(cmd ==input){

}
}

}



- EDIT ---
带有SwingWorker的新Main.class

  package com.sever.core; 

import java.io.IOException;
import java.net.Socket;
import java.util.Scanner;

import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;

public class Main {

private SocketManager network;
public static void main(String [] args){

SwingUtilities.invokeLater(new Runnable(){
@Override
public void run(){
Window window = new Window();
window.setVisible(true);
}
});

SwingWorker server = new SwingWorker(){
@Override
protected Object doInBackground()throws Exception {
Main main = new Main();
main.run();
return null;
}

};
server.run();

}

public void run(){
network = new SocketManager(25595);

while(true){
try {
network.setSocket(network.getServerSocket()。accept());
AddUser(network.getSocket());
线程x =新线程(网络);
x.start();
} catch(Exception e){
System.out.println(无法连接。
}
}

}

public void AddUser(Socket s){
try {
Scanner input = new Scanner (s.getInputStream());
network.addUser(input.nextLine());
} catch(Exception e){

}
}
}


解决方案

您正在从EDT上的Socket读取。这意味着你阻止它。调用invokeLater只会导致您的Runnable在EDT上执行。你在EDT上打了两个调用,其中一个是你的套接字。



考虑在 SwingWorker 将Socker的值逐步返回到GUI。


I know I know, already a million questions and answers on this everywhere. Tons of really detailed articles on it, several types of examples. I've spent the past few hours reading about it, but that's not doing the trick. The reason I'm asking this is because I still don't quiet understand what I need to do apparently because my code is still not working. I get the idea of how Swing works with the EDT, and if I'm going to use the ServerSocket's accept() method I'm going to need to start a new thread for Swing (I think?). When I run my code as it is the window just opens and freezes. My question is could someone look at my code, tell me what I'm doing wrong, and explain it to me like I only have half a brain?(Because that's what I feels like. :P )

Here are some of the places I've read already:

Main.class

package com.sever.core;

import java.io.IOException;
import java.net.Socket;
import java.util.Scanner;

import javax.swing.SwingUtilities;

public class Main { 

private SocketManager network;
public static void main(String[] args){

    SwingUtilities.invokeLater(new Runnable(){
        @Override
        public void run() {
            Window window = new Window();
            window.setVisible(true);
        }       
    });

    SwingUtilities.invokeLater(new Runnable(){
        @Override
        public void run() {
            Main main = new Main();
            main.run();
        }       
    });     


}

public void run(){
    network = new SocketManager(25595);

    while(true){
        try {
            network.setSocket(network.getServerSocket().accept());
            AddUser(network.getSocket());
            Thread x = new Thread(network);
            x.start();
        } catch (Exception e) {
            System.out.println("Failed to connect.");
        }
    }

}

public void AddUser(Socket s){
    try {
        Scanner input = new Scanner(s.getInputStream());
        network.addUser(input.nextLine());
    } catch (Exception e) {

    }
}
}

Window.class

package com.sever.core;

import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.*;

public class Window extends JFrame{

private int screenWidth = 800;
private int screenHeight = 600;
private Thread thread;

private JPanel window = new JPanel();
private JTextArea consle = new JTextArea("Server started....");
private JTextField input = new JTextField();
private JScrollPane consleinput = new JScrollPane(consle);

public Window(){
    this.setName("NAMEHERE - Server Software");
    setResizable(true);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setSize(screenWidth,screenHeight);  
    window.setBackground(Color.DARK_GRAY);
    window.setLayout(new BoxLayout(window, BoxLayout.Y_AXIS));

    consleSetup();
    addComponets();
}

private void addComponets(){
    add(window);
    window.add(consleinput);
    window.add(input);
}

private void consleSetup(){
    consle.setEditable(false);
    consle.setLineWrap(true);
    consle.setBorder(BorderFactory.createEmptyBorder(3,3,3,3)); 
    consleinput.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
    input.setMaximumSize(new             Dimension(Integer.MAX_VALUE,input.getPreferredSize().height));
}

private void addListeners(){
    input.addActionListener(new ActLis());
    input.setActionCommand("input");
}

}

SocketManager.class

package com.sever.core;

import java.io.*;
import java.net.*;
import java.util.ArrayList;

public class SocketManager implements Runnable{

private Socket sock;
private ServerSocket sersoc;
private PrintWriter output;
private BufferedReader input;
private Thread thread;

public ArrayList<Socket> currentConnections = new ArrayList<Socket>();
public ArrayList<String> currentUsers = new ArrayList<String>();


public SocketManager(String ip, int port){
    try{
        sock = new Socket(ip,port);
        PrintWriter output = new PrintWriter(sock.getOutputStream());
        BufferedReader input = new BufferedReader(
                new InputStreamReader(sock.getInputStream()));
        System.out.println("Server: socket started.");
    }catch(Exception e){
        System.out.println("Server: Socket failed to connect.\n");
    }
}

public SocketManager(int port){
    try {
        sersoc = new ServerSocket(port);

    } catch (IOException e) {
        System.out.println("Server: Socket failed to connect.\n");
    }
}

public SocketManager(Socket socket){
    this.sock = socket;

    try{
        output = new PrintWriter(sock.getOutputStream());
        input = new BufferedReader(
                new InputStreamReader(sock.getInputStream()));
    }catch(Exception e){

    }
}

public synchronized void checkConnetion(){
    if(!sock.isConnected()){
        for(int x = 0; x <= currentConnections.size(); x++){
            if(currentConnections.get(x) == sock){
                currentConnections.remove(x);
                System.out.println("Server: Disconnecting from: " + currentConnections.get(x) + "\n");
            }
        }
    }
}

public synchronized Socket getSocket(){
    return sock;
}

public synchronized ServerSocket getServerSocket(){
    return sersoc;
}

public synchronized void setSocket(Socket s){
    System.out.println("Setting socket to: " + s.getInetAddress());
    sock = s;
}

public synchronized void addSocket(Socket s){
    currentConnections.add(s);
}

public synchronized void addUser(String u){
    currentUsers.add(u);
}

public synchronized ArrayList<Socket> getConnections(){
    return currentConnections;
}

public synchronized ArrayList<String> getUsers(){
    return currentUsers;
}

public synchronized void send(String data){
    try{
        output.println(data);
    }catch(Exception e){

    }
}

public synchronized void close(){
    try{
        sock.close();
    }catch(Exception e){

    }
    output = null;
    input = null;
    System.gc();
}

public synchronized boolean isConnected(){
    return (sock == null) ? false : (sock.isConnected() && !sock.isClosed());
}

@Override
public void run() {
    System.out.println("Is runing.");
    while(true){
        try {
            checkConnetion();
            if(input.readLine().isEmpty()){ 
                return;
            }

            output.println("Server: Recived your message.");
        } catch (Exception e) {

        } finally{
            try {
                sock.close();
            } catch (Exception e) {

            }
        }
    }

}

}

ActLis.class

package com.sever.core;

import java.awt.event.*;
import javax.swing.*;

public class ActLis implements ActionListener{

private JTextField actionField;
public ActLis(){

}

public ActLis(JTextField t){
    actionField = t;
}

@Override
public void actionPerformed(ActionEvent e) {
    // TODO Auto-generated method stub
    String cmd = e.getActionCommand();

    if(cmd == "input"){

    }
}

}

--EDIT--- The new Main.class with SwingWorker

package com.sever.core;

import java.io.IOException;
import java.net.Socket;
import java.util.Scanner;

import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;

public class Main { 

private SocketManager network;
public static void main(String[] args){

    SwingUtilities.invokeLater(new Runnable(){
        @Override
        public void run() {
            Window window = new Window();
            window.setVisible(true);
        }       
    });

    SwingWorker server = new SwingWorker(){
        @Override
        protected Object doInBackground() throws Exception {
            Main main = new Main();
            main.run();
            return null;
        }

    };
    server.run();

}

public void run(){
    network = new SocketManager(25595);

    while(true){
        try {
            network.setSocket(network.getServerSocket().accept());
            AddUser(network.getSocket());
            Thread x = new Thread(network);
            x.start();
        } catch (Exception e) {
            System.out.println("Failed to connect.");
        }
    }

}

public void AddUser(Socket s){
    try {
        Scanner input = new Scanner(s.getInputStream());
        network.addUser(input.nextLine());
    } catch (Exception e) {

    }
}
}

解决方案

You are reading from your Socket on the EDT. This means that you block it. Calling invokeLater only causes your Runnable to be executed on the EDT. You are piling two calls on the EDT, one of them being your socket.

Consider moving your socket in a SwingWorker which returns progressively the values of your Socker to the GUI.

这篇关于Java - 线程,Swing和ServerSocket的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆