我有这个类(我的服务器启动类),在这里我为每个新客户创建一个新线程供他使用。 Thread创建之后,我将他添加到Vector(列表)以跟踪活动用户和连接,以便我可以向特定用户发送消息。但我无法从我的线程访问Vector-List(下面的类)。你能解释一下我怎么能这样做?我有一个私人列表和公共setter和getter方法,但我总是得到Vector的大小1。但我测试一下,如果我连接多个客户端,则会有多个具有不同套接字创建的线程。如果我在服务器启动类中使用manuel,我可以将Entrys添加到向量中。
package securemessageserver;
public class SecureMessageServer {
private Vector<SecureMessageServerClientThread> userList = new Vector();
private SSLServerSocket sslserversocket;
int port = 9999;
private Boolean isRunning=true;
SSLSocket sslsocket;
private synchronized void loadCertificat(){
try {
URL url = this.getClass().getResource("/securemessageserver/keystore.jks");
File file = new File(url.toURI());
System.setProperty("javax.net.ssl.keyStore", "C:/keystore.jks");
System.setProperty("javax.net.ssl.keyStorePassword", "Schelkan1994");
//System.setProperty("javax.net.debug","all");
System.out.println("Certifikat geladen");
} catch (URISyntaxException ex) {
Logger.getLogger(SecureMessageServer.class.getName()).log(Level.SEVERE, null, ex);;
stopServer();
}
}
private synchronized void createSocket(){
try {
SSLServerSocketFactory sslserversocketfactory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
sslserversocket = (SSLServerSocket) sslserversocketfactory.createServerSocket(port);
System.out.println("Socket erstellt mit "+port);
} catch (IOException ex) {
Logger.getLogger(SecureMessageServer.class.getName()).log(Level.SEVERE, null, ex);
stopServer();
}
}
private synchronized void startServer(SSLServerSocket sslserversocket){
while(isRunning){
try {
System.out.println("Akzeptiere Verbindungen");
sslsocket = (SSLSocket) sslserversocket.accept();
SecureMessageServerClientThread client = new SecureMessageServerClientThread(sslsocket);
startNewClient(client);
userList.add(client);
} catch (IOException ex) {
Logger.getLogger(SecureMessageServer.class.getName()).log(Level.SEVERE, null, ex);
stopServer();
}
}
}
public synchronized void startNewClient(SecureMessageServerClientThread th){
new Thread(th).start();
}
public synchronized void stopServer(){
isRunning=false;
}
public synchronized SSLServerSocket getServerSocket(){
if(sslserversocket!=null){
return this.sslserversocket;
}
return null;
}
public synchronized void addThreadToList(SecureMessageServerClientThread thread){
userList.add(thread);
}
public synchronized void getAllThreadFromList(){
System.out.println("Size: "+userList.size());
}
public synchronized String getUserName(){
return userList.get(0).getUserOfThread();
}
public synchronized void deleteThreadFromList(SecureMessageServerClientThread thread){
userList.remove(thread);
}
public synchronized void getUserNameOfAllThreads(){
for(int i=0;userList.size()>i;i++){
System.out.println(userList.get(i).getUserOfThread());
}
}
public static void main(String[] args){
SecureMessageServer server = new SecureMessageServer();
server.loadCertificat();
server.createSocket();
server.startServer(server.sslserversocket);
}
}
如果新客户端连接以跟踪连接并执行输入和输出操作,则总是创建此类的另一个类(My Thread Class)instanze。但是我没有从另一个类中的Vector中获得正确的值...你看到我的错误吗?谢谢你的帮助
public class SecureMessageServerClientThread implements Runnable{
private SSLSocket socket;
private String userName;
boolean isRunning=true;
SecureMessageServer server = new SecureMessageServer();
public SecureMessageServerClientThread(SSLSocket socket){
this.socket=socket;
}
private ObjectInputStream sInput;
private ObjectOutputStream sOutput;
@Override
public void run() {
System.out.println("Client mit Socket is Running: "+socket);
while(isRunning){
try {
sInput = new ObjectInputStream(socket.getInputStream());
SecureMessageServerClientMessage msg = (SecureMessageServerClientMessage) sInput.readObject();
if(msg.getType()==0){
System.out.println("All Threads:");
server.getAllThreadFromList();
}else if(msg.getType()==1){
System.out.println(msg.getMessage());
}else if(msg.getType()==2){
Thread.sleep(1000);
socket.close();
this.stopThread();
}else{
System.out.println("Unbekannter Nachrichtentyp");
}
} catch (IOException ex) {
Logger.getLogger(SecureMessageServerClientThread.class.getName()).log(Level.SEVERE, null, ex);
} catch (ClassNotFoundException ex) {
Logger.getLogger(SecureMessageServerClientThread.class.getName()).log(Level.SEVERE, null, ex);
} catch (InterruptedException ex) {
Logger.getLogger(SecureMessageServerClientThread.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
public void stopThread(){
isRunning=false;
// sOutput = new ObjectOutputStream(socket.getOutputStream());
}
public String getUserOfThread(){
return this.userName;
}
public void getUserList(){
server.getAllThreadFromList();
}
}
答案 0 :(得分:1)
在SecureMessageServerClientThread
中,您使用SecureMessageServer server = new SecureMessageServer();
创建新的服务器实例。
这意味着当您在server.getAllThreadFromList()
中致电getUserList
时,您将从刚刚创建的没有客户端的服务器获取列表。
客户端线程应该将服务器实例作为参数:
SecureMessageServer server;
public SecureMessageServerClientThread(SSLSocket socket, SecureMessageServer server){
this.socket=socket;
this.server=server;
}
在服务器中,您应该将this
传递给新的客户端实例:
SecureMessageServerClientThread client = new SecureMessageServerClientThread(sslsocket, this);
答案 1 :(得分:0)
好吧,如果它是私人的,你显然无法从另一个班级访问。保护它并使两个类都在同一个包中。