Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么可以';我不能从静态列表中访问数据吗?_Java_List_Static_Static Variables - Fatal编程技术网

Java 为什么可以';我不能从静态列表中访问数据吗?

Java 为什么可以';我不能从静态列表中访问数据吗?,java,list,static,static-variables,Java,List,Static,Static Variables,我试图从我的列表中访问数据,但它总是以null结尾,或者什么都没有。我运行我的类服务器,它具有公共静态ArrayList clientUsernameList=new ArrayList() 在代码中。如果我的服务器接受套接字,则应出现以下代码 package multi.threaded_server_application; import java.io.DataInputStream; import java.io.IOException; import java.net.ServerS

我试图从我的列表中访问数据,但它总是以null结尾,或者什么都没有。我运行我的
类服务器
,它具有
公共静态ArrayList clientUsernameList=new ArrayList()
在代码中。如果我的服务器接受套接字,则应出现以下代码

package multi.threaded_server_application;

import java.io.DataInputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.time.Clock;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import jdk.nashorn.internal.codegen.CompilerConstants;

/**
*
* @author Seeya
*/
public class Server {

public static ArrayList<String> clientUsernameList = new ArrayList<>();

/**
 * @param args the command line arguments
 * @throws java.io.IOException
 */
public static void main(String[] args) throws IOException {

    int port = 8900;    //Port number the ServerSocket is going to use
    ServerSocket myServerSocket = null;  //Serversocket for sockets to connect
    Socket clientSocket = null;    //Listerner for accepted clients
    ClientThread[] clientsConnected = new ClientThread[20]; //Max clients in this server
    DataInputStream IN = null;

    try {
        myServerSocket = new ServerSocket(port);
        System.out.println("Server waiting for clients on port:" + port);
    } catch (IOException ex) {
        Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
    }

    while (true) {            
        try {   //Freezes while-loop untill a socket have been accepted or if some failure occur
            clientSocket = myServerSocket.accept();
            IN = new DataInputStream(clientSocket.getInputStream());
            String userName = IN.readUTF();
            Server.clientUsernameList.add(userName);

            System.out.println("Client have connected from:" + clientSocket.getLocalAddress().getHostName());
            System.out.println("Username:" + userName);
            System.out.println(Server.clientUsernameList);

        } catch (Exception e) {
            //Print out exception
            System.out.println(e);
        }
        //For-loop that counts every element in Array-clientsConnected
        for (int i = 0; i < clientsConnected.length; i++) {
            //If-statement checks if current element is null 
            if(clientsConnected[i] == null){
                //If current element in the Array is null then create a new object from ClientThread class
                //With a socket and the object of itself as parameter.
                (clientsConnected[i] = new ClientThread(clientSocket, clientsConnected)).start();

                //Must have a break otherwise it will create 20 objects (Exit for-loop)
                break;
            }   //Exit if-statement
        }   //Exit for-loop
    }   //Exit while-loop

}
所有打印出来的内容都是来自我的
类客户机的
[]
。我试图访问静态变量的方式是否有问题

编辑! 这是我用来向服务器中的所有客户端发送/接收消息的代码

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package multi.threaded_server_application;

import com.sun.security.ntlm.Client;
import java.awt.List;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.Clock;
import java.util.ArrayList;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.DefaultListModel;

/**
 *
 * @author Seeya
 */

//THIS CLASS TAKES CARE OF HANDLING MESSAGES TO OTHER CLIENTS!
//-------------------------------------------------------
public class ClientThread extends Thread {

private ClientThread[] clientsConnected;
private Socket SOCKET = null;
private DataInputStream IN = null;
private DataOutputStream OUT = null;
private String userName = null;
//-------------------------------------------------------    
//Constructor
public ClientThread(Socket socket, ClientThread[] clientThread) {
    this.SOCKET = socket;
    this.clientsConnected = clientThread;
}


//This starts as soon as the constructor is done/been created.
@Override
public void run() {
    try {
        //Handleing the messages
        IN = new DataInputStream(SOCKET.getInputStream());
        OUT = new DataOutputStream(SOCKET.getOutputStream());          
        String message = null;

        while (true) {             
            //This will be read second from the socket DataOutPutStream
            //We will use this string to send a message to every client that is online
            message = IN.readUTF();
            //For-loop to check how many people are actually online
            //for (ClientThread k : clientsConnected) = For each client in clientsConnected ends up in variable k
            for (int i = 0; i < clientsConnected.length; i++) {
                    //don't send message to yourself
                if (clientsConnected[i]!= null && clientsConnected[i].userName != this.userName){ 
                    // loops through all the list and calls the objects sendMessage method.
                    clientsConnected[i].sendMessage(message, userName); 
                }
            }
        }

    } catch (IOException ex) {
        Logger.getLogger(ClientThread.class.getName()).log(Level.SEVERE, null, ex);
    }


}

private void sendMessage(String message, String userName) {

    try {            
        Date date = new Date();
        DateFormat format = new SimpleDateFormat("HH:mm:ss");
        OUT.writeUTF(format.format(date) + " " + userName + " says: " + message);
        OUT.flush();

    } catch (IOException ex) {
        Logger.getLogger(ClientThread.class.getName()).log(Level.SEVERE, null, ex);
        System.out.println("Something failed to send message");
    }
}   
}
/*
*要更改此许可证标题,请在“项目属性”中选择“许可证标题”。
*要更改此模板文件,请选择工具|模板
*然后在编辑器中打开模板。
*/
打包多线程服务器应用程序;
导入com.sun.security.ntlm.Client;
导入java.awt.List;
导入java.io.DataInputStream;
导入java.io.DataOutputStream;
导入java.io.IOException;
导入java.net.Socket;
导入java.text.DateFormat;
导入java.text.simpleDataFormat;
导入java.time.Clock;
导入java.util.ArrayList;
导入java.util.Date;
导入java.util.logging.Level;
导入java.util.logging.Logger;
导入javax.swing.DefaultListModel;
/**
*
*@作者西娅
*/
//这个类负责处理发送给其他客户端的消息!
//-------------------------------------------------------
公共类ClientThread扩展线程{
私有客户端线程[]客户端已连接;
私有套接字=空;
私有DataInputStream IN=null;
私有DataOutputStream OUT=null;
私有字符串userName=null;
//-------------------------------------------------------    
//建造师
公共ClientThread(套接字套接字,ClientThread[]ClientThread){
this.SOCKET=SOCKET;
this.clientsConnected=clientThread;
}
//一旦完成/创建了构造函数,就开始执行此操作。
@凌驾
公开募捐{
试一试{
//处理信息
IN=新的DataInputStream(SOCKET.getInputStream());
OUT=新的DataOutputStream(SOCKET.getOutputStream());
字符串消息=null;
虽然(正确){
//这将从套接字DataOutPutStream中读取
//我们将使用此字符串向每个联机的客户端发送消息
message=IN.readUTF();
//用于循环检查实际在线人数
//for(ClientThread k:clientsConnected)=对于clientsConnected中的每个客户机,都以变量k结束
for(int i=0;i
如果您想从服务器字符串中获取客户端用户名,请将其从服务器字符串中删除,您需要通过使用循环创建的套接字向客户端发送用户名,客户端需要在用户名列表中读取代码


我不知道这是否会让你的程序做你想做的事情,但我认为这将是足够的代码来实现这个概念

在您的服务器类中

while (true) {            
    try {   //Freezes while-loop until a socket have been accepted or if some failure occur
        clientSocket = myServerSocket.accept();
        IN = new DataInputStream(clientSocket.getInputStream());
        String userName = IN.readUTF();
        OnConnect(userName); // Where to call the below method.

        System.out.println("Client have connected from:" + clientSocket.getLocalAddress().getHostName());
        System.out.println("Username:" + userName);
        System.out.println(Server.clientUsernameList);

    } catch (Exception e) {
        //Print out exception
        System.out.println(e);
    }


//.... More of your code.
String userNamesCSVs = ""

private void OnConnect(String theNewConnectionName){
    //For-Each loop says for every ClientThread object in clientsConnected do this block of code
    for(ClientThread client : clientsConnected){
        //Construct a long string with comma's in it.
        userNamesCSVs = userNamesCSVs + client.userName + ",";
    }
    //Don't forget to count the new name! This was added so you didn't have to do 
    //tricky stuff in the above for loop with the trailing comma. Also the server
    //doesn't have your user name yet.
    userNamesCSVs = userNamesCSVs + theNewConnectionName;
    //New for loop to start sending a mass message. Same as before.
    for(ClientThread client : clientsConnected){
        client.sendMessage(userNamesCSVs, userName);
    }
    //Remember take that static off clientUsernameList. Look up static it's not what you want here.

clientUsernameList.add(userName);
}

在客户端类中,从服务器接收消息。

String[] userNameArray = new String[20]; //Max users and what not.
//Same method you are using named check for messages. It's needed to get the data from the server.
private void getUserNames(DataInputStream in) throws IOException{
    try {
        String userNames = in.readUTF();        
        System.out.println(IncomingMessage);
        userNameArray = userNames.split(",")
    } catch (Exception e) {
        System.err.println(e);
    }
    for(String user : userNames){
        GUI.writeGuid("User connected: " + user);
    }
}

旁注:


另一个要查找的是和字节流以及其他类似的很酷的东西。一旦掌握了通过客户机和服务器来回发送字符串的方法,就很容易做到这一点。基本上,只要可序列化,您就可以发送整个对象,而不仅仅是字符串。

您的类名为
Server
还是
多线程服务器应用程序
?从你展示的内容来看,你在一节课上写清单,在另一节课上读清单。哦,对不起。它被称为多线程服务器应用程序,但我重新命名了它,因为这对服务器来说是一个非常糟糕的名字。你没有在你的问题中提供足够的信息。请以我们能够在那里重新编写的方式发布代码的最小工作示例。这是我使用列表的两个类。希望这能帮上忙。我以前觉得很好。。。
String[] userNameArray = new String[20]; //Max users and what not.
//Same method you are using named check for messages. It's needed to get the data from the server.
private void getUserNames(DataInputStream in) throws IOException{
    try {
        String userNames = in.readUTF();        
        System.out.println(IncomingMessage);
        userNameArray = userNames.split(",")
    } catch (Exception e) {
        System.err.println(e);
    }
    for(String user : userNames){
        GUI.writeGuid("User connected: " + user);
    }
}