ObjectOutputStream 不更新
ObjectOutputStream not updating
我在服务器上工作,其中服务器class 为每个连接的客户端创建一个新线程,当客户端连接时,ObjectOutputStream 不会在几个连接的客户端上刷新。它停留在最后连接的客户端 OutputObjectStream
这是服务器初始化函数
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.ObjectOutputStream@3933c336 (New client (1) connected)
Client connected
java.io.ObjectOutputStream@5adada9e (New client (2) connected)
java.io.ObjectOutputStream@5adada9e (Sending to first client)
编辑
为什么 ObjectOutputStream 不刷新,并使用从一开始就分配给它的输出流,而不是最新的输出流?
编辑
忘记加上write函数,以及打印的地方
编辑
添加了整个 ServerThread class
这是静态混淆的情况。
Java中的关键字static
表示完全独立于此class实例的组件(变量或方法)。对于变量,这意味着只有一个变量副本供所有实例共享,而不是每个实例都有一个单独的副本(即非静态变量)。
因为实例共享静态变量,它的值对于所有实例总是相同的。如果您更改一个实例中的值,它也会在所有其他实例中更改。
在您的例子中,您对 ObjectInputStream
和 ObjectOutputStream
使用了 static
,因此它们无法更改:关键字 final
使变量不可更改。请注意,这只会使赋值变得不可能,而不会改变赋值对象的内部值(例如通过 setter)。它只是阻止您创建新对象并将其放入最终变量。
我在服务器上工作,其中服务器class 为每个连接的客户端创建一个新线程,当客户端连接时,ObjectOutputStream 不会在几个连接的客户端上刷新。它停留在最后连接的客户端 OutputObjectStream
这是服务器初始化函数
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.ObjectOutputStream@3933c336 (New client (1) connected)
Client connected
java.io.ObjectOutputStream@5adada9e (New client (2) connected)
java.io.ObjectOutputStream@5adada9e (Sending to first client)
编辑 为什么 ObjectOutputStream 不刷新,并使用从一开始就分配给它的输出流,而不是最新的输出流?
编辑 忘记加上write函数,以及打印的地方
编辑 添加了整个 ServerThread class
这是静态混淆的情况。
Java中的关键字static
表示完全独立于此class实例的组件(变量或方法)。对于变量,这意味着只有一个变量副本供所有实例共享,而不是每个实例都有一个单独的副本(即非静态变量)。
因为实例共享静态变量,它的值对于所有实例总是相同的。如果您更改一个实例中的值,它也会在所有其他实例中更改。
在您的例子中,您对 ObjectInputStream
和 ObjectOutputStream
使用了 static
,因此它们无法更改:关键字 final
使变量不可更改。请注意,这只会使赋值变得不可能,而不会改变赋值对象的内部值(例如通过 setter)。它只是阻止您创建新对象并将其放入最终变量。