应用程序不进入线程

时间:2017-11-22 15:22:24

标签: java multithreading sockets server serversocket

我尝试使用多线程功能创建聊天应用程序,这里是处理连接和接受连接的服务器类的会话类的代码:

会话班:

public class Session extends Thread{

Socket Sock;
BufferedReader din;
PrintWriter dout;
Thread receive;
Server serv;
boolean connected = false;
String lineSep = System.getProperty("line.separator");

public Session(Socket s, Server n){

    super("ThreadSessions");
   this.Sock = s;
   this.serv = n;

}

public void run(){
    try{
    din = new BufferedReader(new InputStreamReader(Sock.getInputStream()));
    dout = new PrintWriter(Sock.getOutputStream());
    connected = true;
    Receive();

    }
    catch(IOException ioe){
        ioe.printStackTrace();
    }

    receive.start();
}

public void sendTo(String text){
    dout.write(text);
    dout.flush();
}

public void sendToAll(String text){
    for(int ind = 0; ind < serv.sessions.size(); ind++){
        Session s = serv.sessions.get(ind);
        s.sendToAll(text);
    }
}

public void Receive(){
    receive = new Thread(new Runnable(){

        @Override
        public void run() {
            receive = new Thread(new Runnable(){
                String msgIn;
                    public void run() {

                        while(connected){
                        try{
                            msgIn = din.readLine(); 

                            if(msgIn != "" || msgIn != null){

                            System.out.println(msgIn);
                            msgIn = "";
                            }else{

                            }

                        }
                        catch(SocketException exc){
                            exc.printStackTrace();
                        } catch (IOException e) {

                            e.printStackTrace();
                        }
                       }
                    } 
            });
        }

  });
 }
}

服务器类:

public class Server {

private JFrame frame;
private JTextField txtPort;
JTextArea textArea, textSessions;

String lineSep = System.getProperty("line.separator");

ServerSocket ServSock;
Socket Sock;
String port;
public JTextField textField;
int numbSess = 0, actSess = 0;
ArrayList<Session> sessions = new ArrayList<Session>();
boolean shouldRun = true;



public static void main(String[] args) 
{
    Server window = new Server();
    window.frame.setVisible(true);
}


   public Server() {
    initializeComponents(); //This void initializes the graphic components
   }

 private void Connect(){
  port = txtPort.getText();
  int portN = 0;

   try{
    portN = Integer.parseInt(port);
     }
   catch(NumberFormatException exc)
    {
     exc.printStackTrace();
    } 


 try{

ServSock = new ServerSocket(9081);
while(shouldRun){

Sock = ServSock.accept();

String ip = Sock.getInetAddress().getHostAddress();

Session s = new Session(Sock, this);
s.start();
sessions.add(s);    

numbSess++;

 }
 }
 catch(Exception exc){
     exc.printStackTrace();
     System.exit(3);
   }
 }


private void initializeComponents() {
    [...]

    Button btnConn = new JButton("Open Connection");
    btnConn.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            Connect();
        }
    });
    btnConn.setBackground(new Color(0, 0, 0));
    btnConn.setForeground(new Color(0, 128, 0));
    btnConn.setBounds(160, 13, 137, 25);
    frame.getContentPane().add(btnConn);
    [...]
  }

我想要做的是创建一个可以同时处理更多连接的聊天应用程序,而不是输入第一个连接(我的应用程序中的会话),它继续等待其他连接并在arrayList中添加它们。 可能代码充满了错误,请原谅我。 如果有人知道更好的方法来创建一个可以处理更多客户端连接的服务器,那么欢迎这些。 希望有人可以帮助我,提前谢谢。

1 个答案:

答案 0 :(得分:0)

  

而不是输入第一个连接(我的应用程序中的会话),它继续等待其他连接并在arrayList中添加它们

这是由于您的线程设置方式

每次创建和启动会话时,都会调用其run方法...

public void run()
{
    Receive();
    [...]
    receive.start();
}

...然后在receive

中设置Receive();
public void Receive()
{
    receive = new Thread(new Runnable()
    {
        public void run()
        {
            receive = new Thread(new Runnable()
            {
                public void run()
                {
                    //your actual code that you wanted to run
                }
            });
        }
    });
}

运行时创建的线程将执行一项操作,再次使用您想要的代码再次设置receive

receive = new Thread(new Runnable()
{
    public void run()
    {
        //your actual code that you wanted to run
    }
});

但是在致电Receive();后,您只拨打了receive.start();一次

您需要调用两次,并以某种方式确保及时更新,或者只删除多余的线程