0

Я работаю на сервере, где серверный класс создает новый поток для каждого подключенного клиента, а когда клиент подключен, ObjectOutputStream не будет обновляться на серверных подключенных клиентах. Он застрял на последних подключенных клиентов OutputObjectStreamObjectOutputStream не обновляется

Это функция сервера инициализации

private void init(Server s) 
    { 
    ServerSocket server = null; 
    Socket c = null; 
    ServerThread tmp = null; 
    try 
    { 
     this.db = new Database(); 
     server = new ServerSocket(6789); 
     System.out.println("Listening on 6789"); 
     while(true) 
     { 
      c = server.accept(); 
      tmp = new ServerThread(c, s); 
      clients.add(tmp); 
      new Thread(tmp).start(); 
     } 
    }catch(IOException | SQLException e) 
    { 
     e.printStackTrace(); 
     System.exit(1); 
    } 

Это конструктор и запустить функцию ServerThread:

package server; 

import java.io.EOFException; 
import java.io.IOException; 
import java.io.ObjectInputStream; 
import java.io.ObjectOutputStream; 
import java.net.Socket; 
import java.sql.SQLException; 
import java.util.ArrayList; 
import java.util.HashMap; 

import scripts.Response; 

import com.sun.rowset.CachedRowSetImpl; 

public class ServerThread implements Runnable 
{ 
public static ObjectOutputStream output; 
private static ObjectInputStream input; 
private Socket client = null; 
private Server server = null; 
private Response line = null; 
private String usr; 

public ServerThread(Socket c, Server server) throws IOException 
{ 
    this.client = c; 
    this.server = server; 
    this.output = new ObjectOutputStream(client.getOutputStream()); 
    output.flush(); 
    output.reset(); 
    this.input = new ObjectInputStream(client.getInputStream()); 
} 

public void run() 
{ 
    try 
    {    
     System.out.println("Client connected"); 

     write(new Response("200","Time to login")); 
     while((line = (Response)input.readObject()) != null) 
     { 
      read_code(line); 
     } 
    }catch(EOFException e){ 
     System.out.println("EOFException, probably end of stream"); 

    }catch(IOException e) 
    { 
     e.printStackTrace(); 
     Thread.currentThread().interrupt(); 
    }catch(ClassNotFoundException cnfe) 
    { 
     cnfe.printStackTrace(); 
    } catch (SQLException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
} 

public void alert_user(String q) throws IOException 
{ 
    System.out.println("In thread "+q); 
    write(new Response("404", "You are being alerted!")); 
} 

private void read_code(Response response) throws IOException, SQLException 
{ 
    HashMap tmp_response = response.extract_map(); 
    switch ((String)tmp_response.get("code")) 
    { 
     case "420": 
      usr_login(tmp_response); 
      break; 
     case "430": 
      select_query((String)tmp_response.get("to_select"), (String)tmp_response.get("table"), (String)tmp_response.get("rest")); 
      break; 
     case "431": 
      /** 
      * server.alertUsers(ArrayList<String> usernames); if there is users that has to be alerted 
      */ 
      insert_query((String)tmp_response.get("table"), (ArrayList<String>)tmp_response.get("columns"), (ArrayList<String>)tmp_response.get("values")); 
      break; 
     default: 
      System.out.println("Unrecognized command"); 
    } 
} 

private void usr_login(HashMap tmp_response) throws IOException 
{ 
    String usr = (String) tmp_response.get("username"); 
    String pass = (String) tmp_response.get("password"); 
    boolean login = server.query_login(usr, pass); 
    System.out.println(login); 
    if(login) 
    { 
     write(new Response("9001", "Login Successfull!")); 
     this.usr = usr; 
    }else 
     write(new Response("8999", "Login Unsuccessfull!")); 
} 

private void insert_query(String table, ArrayList<String> columns, ArrayList<String> values) throws IOException, SQLException 
{ 
    CachedRowSetImpl rows = server.insert_query(table, columns, values); 
    write(new Response("3", rows)); 
} 

private void select_query(String to_select, String table, String rest) throws SQLException, IOException 
{ 
    CachedRowSetImpl rows = server.select_query(to_select, table, rest); 
    write(new Response("2", rows)); 
} 

private void write(Response resp) throws IOException 
{ 
    System.out.println(output.toString()); 
    System.out.println(client.toString()); 
    output.reset(); 
    output.writeObject(resp); 
    output.flush(); 
} 

public String get_user() 
{ 
    return usr; 
} 

}

Так что, когда я попробуйте распечатать объекты, я получаю это

Client connected 
    java.io.ObjectOutputStrea[email protected] (New client (1) connected) 
    Client connected 
    [email protected] (New client (2) connected)  
    [email protected] (Sending to first client) 

EDIT Почему ObjectOutputStream не обновляет и использует выходной поток, которому он был назначен с самого начала, а не последний?

EDIT Забыл добавить функцию записи, и где печатаются

EDIT Добавлен весь класс ServerThread

+0

'write()' вызывается только один раз для каждого клиента. Возможно, есть еще один вызов в 'read_code', и в этом случае мне тоже нужно будет это ответить. – Soana

+0

Добавлено полностью ServerThread –

ответ

0

Это случай статической путаницы.

Ключевое слово static в Java обозначает компонент (переменную или метод), который полностью не зависит от экземпляров этого класса. Для переменных это означает, что имеется только одна копия переменной для всех экземпляров, а не отдельная копия для каждого экземпляра (т. Е. Нестатические переменные).

Поскольку экземпляры разделяют статическую переменную, ее значение всегда одинаково для всех экземпляров. Если вы измените значение в одном экземпляре, оно также изменится во всех других случаях.


В вашем случае, если вы использовали static для ObjectInputStream и ObjectOutputStream так, что они не могут быть изменены: ключевое слово final делает переменную неизменна. Обратите внимание, что это делает невозможным присвоение, не изменяя внутренние значения назначенного объекта (например, через сеттер). Это просто мешает вам создать новый объект и вставить его в конечную переменную.