الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

Why I have this NullPointerException ?!

مغلق
بدأه موظف في 28 مارس 2006 · 5 رد · 744 مشاهدة · في JavaSE
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

أحاول حل سؤال عن ال Multithreading بين client و server، المفترض أن ال client يستيطع إرسال أربع أوامر فقط ويتعامل مع كل منها ال server بالشكل التالي:

1-إن أرسل ال client الأمر ADD filename فإن ال server سيضيف إسم الملف إلى ال data structure التي ستخزن أسماء الملفات في ال server.

2-إن أرسل ال client الأمر LSF فإن السيرفر سيقوم بعرض قائمة بأسماء الملفات التي يحويها.

3-إن أرسل ال client الأمر SRC فإن السيرفر سيقوم بعرض رقم ال ID لل file's owner.

4- إن أرسل ال client الأمر QUIT فسيخرج.

الحاصل أني أواجه مشكلة NullPointerException ، أظن أنها مع variable إسمه clientCommand لكن بحسب علمي أني قد أعلنت له object مسبقاً فهو يستطيع وعملت له initialization فلا أعلم مشكلة فيه!.

هل أحد من الأخوة يستطيع مساعدتي في الأمر...

الكودين كالتالي:

Server code:

//kazaaServer.java : The Server application

import java.net.*;
import java.io.*;
import java.util.*;	// for Tokenizer

public class KazaaServer
{
    ServerSocket m_ServerSocket;
    String[] files = new String[100];


    public KazaaServer()
    {
        try
        {
            // Create the server socket.
            m_ServerSocket = new ServerSocket(12111);
        }
        catch(IOException ioe)
        {
            System.out.println("Could not create server socket at 12111. Quitting.");
            System.exit(-1);
        }

        System.out.println("Listening for clients on 12111...");

        // Successfully created Server Socket. Now wait for connections.
        int id = 0;
        while(true)
        {
            try
            {
                // Accept incoming connections.
                Socket clientSocket = m_ServerSocket.accept();

                // accept() will block until a client connects to the server.
                // If execution reaches this point, then it means that a client
                // socket has been accepted.

                // For each client, we will start a service thread to
                // service the client requests. This is to demonstrate a
                // multithreaded server, although not required for such a
                // trivial application. Starting a thread also lets our
                // EchoServer accept multiple connections simultaneously.

                // Start a service thread

                ClientServiceThread cliThread = new ClientServiceThread(clientSocket, id++);
                cliThread.start();
            }
            catch(IOException ioe)
            {
                System.out.println("Exception encountered on accept. Ignoring. Stack Trace :");
                ioe.printStackTrace();
            }
        }
    }	// public KazaaServer

    public static void main (String[] args)
    {
        new KazaaServer();
    }


    class ClientServiceThread extends Thread
    {
        Socket m_clientSocket;
        int m_clientID = -1;
        boolean m_bRunThread = true;

        ClientServiceThread(Socket s, int clientID)
        {
            m_clientSocket = s;
            m_clientID = clientID;
        }

        public void run()
        {
            // Obtain the input stream and the output stream for the socket
            // A good practice is to encapsulate them with a BufferedReader
            // and a PrintWriter as shown below.
            String clientCommand = new String();
            clientCommand=" ";
            BufferedReader in = null;
            PrintWriter out = null;
            int ID=0;

            // Print out details of this connection
            System.out.println("Accepted Client : ID - " + m_clientID + " : Address - " +
                             m_clientSocket.getInetAddress().getHostName());

            try
            {
                in = new BufferedReader(new InputStreamReader(m_clientSocket.getInputStream()));
                out = new PrintWriter(new OutputStreamWriter(m_clientSocket.getOutputStream()));

                // At this point, we can read for input and reply with appropriate output.

                // Run in a loop until m_bRunThread is set to false
                while(m_bRunThread)
                {
                    //String clientCommand = new String();
                    //clientCommand= " ";
                    // read incoming stream
                   // BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
                    //String clientCommand = "";
                    clientCommand = in.readLine();

                    String[] tokens = new String[2];
                    StringTokenizer st = new StringTokenizer(clientCommand," ");


                    int i=0;
                    while (st.hasMoreTokens() ) {
      tokens[i++] = st.nextToken();
      }


   	 if(tokens[0]=="ADD"){
      files[ID++]=tokens[1];
   	 }

   	 if(tokens[0]=="SRC"){
      for(i=0;i<ID;i++){
     	 if(tokens[1]==files){
        out.print("the owner is :");
        out.println(i);
     	 }
      }

   	 }

   	 if(clientCommand.equalsIgnoreCase("LSF"))
                    {
      for(i=0;i<ID;i++){
     	 out.println(files);
      }
   	 }

                    if(clientCommand.equalsIgnoreCase("quit"))
                    {
                        // Special command. Quit this thread
                        m_bRunThread = false;
                        System.out.print("Stopping client thread for client : " + m_clientID);
                    }
                    else
                    {
                        // Echo it back to the client.
                        out.println(clientCommand);
                        out.flush();
                    }

                } //while
            } //try
            catch(Exception e)
            {
                e.printStackTrace();
            }
            finally
            {
                // Clean up
                try
                {
                    in.close();
                    out.close();
                    m_clientSocket.close();
                    System.out.println("...Stopped");
                }
                catch(IOException ioe)
                {
                    ioe.printStackTrace();
                }
            }//finally
        } //run
    } //ClientServiceThread
} // kazaaserver

Client code:

//KazaaClient.java : The client application

import java.net.*;
import java.io.*;
import java.util.*;





// A client for our multithreaded EchoServer.
public class KazaaClient
{


    public static String[] args= new String[1];//{PC148716230145};
    public static void main(String[] args)
    {


        // First parameter has to be machine name
  args[0]="127.0.0.1";//if it doesn't work within your JDT,you compile the .java file then take the .class file copy it in \bin directory in j2sd directory then run it from DOS prompt
        if(args.length == 0)
        {
            System.out.println("Usage : EchoClient <serverName>");
            return;
        }

        Socket s = null;

        // Create the socket connection to the EchoServer.
        try
        {
            s = new Socket(args[0], 12111);
        }
        catch(UnknownHostException uhe)
        {
            // Host unreachable
            System.out.println("Unknown Host :" + args[0]);
            s = null;
        }
        catch(IOException ioe)
        {
            // Cannot connect to port on given host
            System.out.println("Cant connect to server at 12111. Make sure it is running.");
            s = null;
        }

        if(s == null)
            System.exit(-1);

        BufferedReader inCommand = null;
        PrintWriter out = null;
        String line;

        try
        {
            // Create the streams to send and receive information
            inCommand = new BufferedReader(new InputStreamReader(s.getInputStream()));
            out = new PrintWriter(new OutputStreamWriter(s.getOutputStream()));



 	 System.out.print("Enter your command: ");

 	 //  read the command from the command-line; need to use try/catch with the
      //  readLine() method
      BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
      String cmd = null;
         try {
            cmd = br.readLine();
         } catch (IOException ioe) {
              System.out.println("IO error trying to read your command!");
              System.exit(1);
        }
        out.print(cmd);
 	 //  open up standard input
 	 //BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

      /*String cmd = null;
      String[] tokens = new String[2];

      //  read the command from the command-line; need to use try/catch with the
      //  readLine() method
      try {
         cmd = br.readLine();
      } catch (IOException ioe) {
           System.out.println("IO error trying to read your command!");
           System.exit(1);
        }

        StringTokenizer st = new StringTokenizer(cmd, " ,\t");
        int i=0;
     while (st.hasMoreTokens()) {
         tokens[i++] = st.nextToken();
 	 }



 	 System.out.println(tokens[0]);*/

        }
        catch(IOException ioe)
        {
            System.out.println("Exception during communication. Server probably closed connection.");
        }
        finally
        {
            try
            {
                // Close the streams
                out.close();
                inCommand.close();
                // Close the socket before quitting
                s.close();
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
        }
    }
}
#2

تعطينا الشفرة دون الخطأ!

اطبع لنا هنا الخطأ الذي تواجهه كاملا!

#3

أعتذر :s ، فاتني طباعة الخطأ...

في ال client أطبع التالي:

C:\j2sdk1.4.2\bin>java KazaaClient 127.0.0.1
Enter your command: ADD filename

C:\j2sdk1.4.2\bin>

في ال server أجد التالي:

Listening for clients on 12111...
Accepted Client : ID - 0 : Address - localhost
java.lang.NullPointerException
        at java.util.StringTokenizer.<init>(StringTokenizer.java:146)
        at java.util.StringTokenizer.<init>(StringTokenizer.java:162)
        at KazaaServer$ClientServiceThread.run(KazaaServer.java:111)
...Stopped
#4

شكلك تقرأ null هنا:

clientCommand = in.readLine();

                   String[] tokens = new String[2];
                   StringTokenizer st = new StringTokenizer(clientCommand," ");

جرب :

clientCommand = in.readLine();
System.out.println("Received Command is: "+clientCommand);
                   String[] tokens = new String[2];
                   StringTokenizer st = new StringTokenizer(clientCommand," ");

ولو كان صحيحا،، ربما لو أعدت القراءة من جديد مثلا:

while(clientCommand==null){
clientCommand = in.readLine();
}
                   String[] tokens = new String[2];
                   StringTokenizer st = new StringTokenizer(clientCommand," ");

هذا من غير ما أجرب حقيقة الشفرة في الأعلى..

بالتوفيق!

#5

السلام عليكم ورحمة الله...

أخي حسام...

كما قلت، تبين أني أقرأ null و قمت بالتخلص من هذه المشكلة بحمدلله كما أشرت، لكن بعد أن أردت إكمال المطلوب بالسؤال ظهر لي مشكلة أخرى، فلا أستطيع عرض أسماء الملفات المدخلة كما هو يجب، إنما ما يعرض هو أسماء عملت لها Initialaization مسبقاً،حقيقة حاولت كثيراً إصلاح الأمر لكن لم أنجح!.

هل لك مشكوراً أنت أو أي أحد من الإخوة بالإطلاع على الكود كاملاً علك تجد العلة فيه.

كود ال client لم يتغير..

أما كود ال server فنسخته الأخيرة التي وقفت عندها كالتالي:

//kazaaServer.java : The Server application

import java.net.*;
import java.io.*;
import java.util.*;	// for Tokenizer



public class KazaaServer
{



    int ID=0;
    static int no_files=0;
    int tok=0;
    ServerSocket m_ServerSocket;




    public KazaaServer()
    {
        try
        {
            // Create the server socket.
            m_ServerSocket = new ServerSocket(12111);
        }
        catch(IOException ioe)
        {
            System.out.println("Could not create server socket at 12111. Quitting.");
            System.exit(-1);
        }

        System.out.println("Listening for clients on 12111...");

        // Successfully created Server Socket. Now wait for connections.
        int id = 0;
        while(true)
        {
            try
            {
                // Accept incoming connections.
                Socket clientSocket = m_ServerSocket.accept();

                // accept() will block until a client connects to the server.
                // If execution reaches this point, then it means that a client
                // socket has been accepted.

                // For each client, we will start a service thread to
                // service the client requests. This is to demonstrate a
                // multithreaded server, although not required for such a
                // trivial application. Starting a thread also lets our
                // EchoServer accept multiple connections simultaneously.

                // Start a service thread

                ClientServiceThread cliThread = new ClientServiceThread(clientSocket, id++);
                cliThread.start();
            }
            catch(IOException ioe)
            {
                System.out.println("Exception encountered on accept. Ignoring. Stack Trace :");
                ioe.printStackTrace();
            }
        }
    }	// public KazaaServer

    public static void main (String[] args)
    {
        new KazaaServer();

    }


    class ClientServiceThread extends Thread
    {
        Socket m_clientSocket;
        int m_clientID = -1;
        boolean m_bRunThread = true;


        ClientServiceThread(Socket s, int clientID)
        {
            m_clientSocket = s;
            m_clientID = clientID;
        }

        public void run()
        {
            // Obtain the input stream and the output stream for the socket
            // A good practice is to encapsulate them with a BufferedReader
            // and a PrintWriter as shown below.
            //String clientCommand = new String();
            //clientCommand=" ";
            BufferedReader in = null;
            PrintWriter out = null;


            // Print out details of this connection
            System.out.println("Accepted Client : ID - " + m_clientID + " : Address - " +
                             m_clientSocket.getInetAddress().getHostName());

            try
            {
                in = new BufferedReader(new InputStreamReader(m_clientSocket.getInputStream()));
                out = new PrintWriter(new OutputStreamWriter(m_clientSocket.getOutputStream()));




                while(m_bRunThread)
                {


        String files[] = new String[10];
        for(int k=0;k<files.length;k++)
       	 files[k]="file";

        String tokens[]=new String[2];
        for(int k=0;k<tokens.length;k++)
       	 tokens[k]="token";

        String temclientCommand = new String();
        String clientCommand = new String();
        clientCommand = in.readLine();
        if (clientCommand != null){
         temclientCommand = clientCommand;
        }

   	 StringTokenizer st = new StringTokenizer(temclientCommand," ");
   	 int i=0;
   	 while (st.hasMoreTokens()) {

      tokens = st.nextToken();
      i++;
   	 }



   	 if(tokens[0].equalsIgnoreCase("ADD")){
      if(files[ID] != null){
     	 files[ID]=tokens[1];
      }
      no_files++;
      ID++;
   	 }


   	 /*if(temclientCommand.equalsIgnoreCase("SRC")){
      for(i=0;i<ID;i++){
     	 if(tokens[1]==files){
        out.print("the owner is :");
        out.println(i);
     	 }
      }

   	 }*/

   	 if(temclientCommand.equalsIgnoreCase("LSF"))
                    {

      for(i=0;i<no_files;i++){
     	 System.out.println(files);
      }
   	 }

                    if(temclientCommand.equalsIgnoreCase("quit"))
                    {
                        // Special command. Quit this thread
                        m_bRunThread = false;
                        System.out.print("Stopping client thread for client : " + m_clientID);

                    }
                    else
                    {
                        // Echo it back to the client.
                        out.println(temclientCommand);
                        out.flush();
                    }

                } //while
            } //try
            catch(Exception e)
            {
                e.printStackTrace();
            }
            finally
            {
                // Clean up
                try
                {
                    in.close();
                    out.close();
                    m_clientSocket.close();
                    System.out.println("...Stopped");
                }
                catch(IOException ioe)
                {
                    ioe.printStackTrace();
                }
            }//finally
        } //run
    } //ClientServiceThread
} // kazaaserver
#6

أخي حسام...

تنبتهت لشيء الآن،كنت أفكر بعقلية ال single thread ونسيت أن العمل قائم على أساس ال multithreads...!

الآن أتصور الأمر كالتالي: عندما يرسل ال client الأمر LSF فإن أسماء الملفات لا تظهر لأن من قام بتخزينها هي thread أخرى.

كيف أنشأ مصفوفة مشتركة بين ال two threads لكي تخزن ال thread الأولى بها أسماء الملفات،وتقوم ال thread الأخرى بالوصول وإستخدام هذه المعلومات؟!

هذا الموضوع مغلق.

مواضيع مشابهة