【问题标题】:Buffered Reader Hanging in Java缓冲阅读器挂在 Java 中
【发布时间】:2015-02-06 18:24:18
【问题描述】:

我的任务是为我的一项编程任务制作一个简单的 Java 服务器。这一点,我没有问题。服务器本质上是一个存储音乐数据的点唱机。 (它实际上并没有为分配目的存储任何音乐)客户端应该能够与此服务器交互以添加歌曲、查看歌曲列表并增加歌曲的流行度。完成其中一项操作后,客户端将断开连接。这一点,我实施没有问题。我用套接字和服务器套接字制作了一个简单的多线程服务器。我已经在 telnet 中对其进行了测试,并且所有所需的功能都运行良好。我的问题来自我们必须做的一些测试。为了正式测试服务器,我们将创建一个 java 类,它只创建一堆客户端套接字并让它们与服务器交互。这是一个例子。

public class LikeTunesServerTest    {

public static void main(String[] args)  {

    try {

        Socket client = new Socket("localhost", 12010);
        BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
        PrintWriter out = new PrintWriter(new OutputStreamWriter(client.getOutputStream()));
        out.println("0");  // add tune
        out.println("The Beatles");
        out.println("Yellow Submarine");
        out.flush();
        client.close();

        client = new Socket("localhost", 12010);
        in = new BufferedReader(new InputStreamReader(client.getInputStream()));
        out = new PrintWriter(new OutputStreamWriter(client.getOutputStream()));
        out.println("2"); // request all tunes in alphabetical order
        String line;
        while ((line = in.readLine()) != null) {
            System.out.println(line);
        }
        client.close();

    }

    catch (IOException e)   {

        System.out.println("e");

    }
}
}

据我所知,第一个客户端成功完成交互并退出。然后,第二个客户端连接但程序然后只是挂起。该程序应该打印出 The Beatles/nYellow Submarine/n0 。我猜这与我的 BufferedReader 的 while 循环有关,但老实说,我不知道,我在学习的 JAVA IO 方面并不是最好的。如果有人可以帮助我推断导致挂起的原因以及为什么没有打印出来,我将不胜感激。作为参考,这里是一个服务器程序的 sn-p,它显示了服务器如何处理客户端。

 try    {

        // Open I/O

        in = new BufferedReader(new InputStreamReader(incomingConnection.getInputStream()));
        out = new PrintStream(incomingConnection.getOutputStream());

        // Ask for input (For Telnet Testing)

        //out.println("Welcome to the LikeTunes Server!.");
        //out.println("Type 0 to add a tune to the list.");
        //out.println("Type 1 to like an existing Tune.");
        //out.println("Type 2 to view the list of Tunes in alphabetical order.");
        //out.println("Type 3 to view the list of Tunes in order of popularity.");
        try {

            final int temp = Integer.parseInt(in.readLine());

            // Add a Tune to the TuneLst

            if (temp == 0)  {

                // Get Tune to be added
                // TuneList method is synchronised to prevent duplicates

                //out.println("Please input the name of the artist.");
                String artistName = new String(in.readLine());
                //out.println("Please input the name of the Tune.");
                String title = new String(in.readLine());

                // If the client leaves an artist's name or title blank

                if (artistName.equals("") || title.equals(""))  {

                    out.println("5");
                }

                // Otherwise, add the Tune

                else    {

                    successCheck = LikeTunesServer.tl.addTune(artistName,title);

                    // Tune was added successfully 

                    if (successCheck == 1)
                    out.println("Request Completed, closing server");

                    // Tune was a duplicate

                    else
                    out.println("Tune was a duplicate, closing server");
                }
            }

            // Like a Tune on the TuneList

            else if (temp == 1) {

                // Get Tune to be liked
                // TuneList method is synchronised to prevent incorrect Tune likes

                //out.println("Please input the name of the artist.");
                String artistName = new String(in.readLine());
                //out.println("Please input the name of the Tune.");
                String title = new String(in.readLine());

                // If the client leaves an artist's name or title blank

                if (artistName.equals("") || title.equals(""))  {

                    out.println("5");
                }

                // Otherwise, like the Tune

                else    {

                    successCheck = LikeTunesServer.tl.likeTune(artistName,title);

                    // Tune was liked successfully

                    if (successCheck == 1)
                    out.println("Request Completed, closing server");

                    // Tune was not there to like

                    else
                    out.println("Could not like Tune, it does not exist on the server yet!");
                }
            }

            // List Tunes Alphabetically

            else if (temp == 2) {

                String result = new String(LikeTunesServer.tl.listAlphabetically());
                out.println(result);
                out.println("Request Completed, closing server");
            }

            // List Tunes by Popularity

            else if (temp == 3) {

                String result = new String(LikeTunesServer.tl.listByLikes());
                out.println(result);
                out.println("Request Completed, closing server");
            }

            // Client made an unrecognised request

            else    {

                out.println("7");
            }
        }

Tunelist.java 中的方法

    public String listAlphabetically()  {

    String result = new String();
    Tune currentTune = theListAlph;

    // Loops through the alphabetical list concatenating the Tune's info to the result string

    for (int i = 0; i < length(); i++)  {

        if  (i == 0)    {

            result = currentTune.returnTune();

        }

        else    {

            result = result.concat(currentTune.returnTune());

        }

        currentTune = currentTune.nextAlph;

    }

    return result;

}



 public synchronized int addTune(String artistName, String title)   {

    // If the list is empty, add the first Tune

    int temp = 0;
    if  (theListAlph == null)   {

        Tune newNode = new Tune(artistName, title);
        theListAlph = newNode;
        theListPop = newNode;
        temp = 1;

    }

    // Otherwise, begin searching this List for the new Tune's correct lexicographical position in the Linked List

    else    {

        Tune currentTune = theListAlph;
        while (temp == 0)   {

            String testArtist = currentTune.artistName;
            String newArtist = artistName;
            int compare = newArtist.compareTo(testArtist);

            // This artist of the new Tune comes before the tested artist alphabetically

            if (compare < 0)    {

                Tune newNode = new Tune(artistName, title);

                // If the tested Tune was the first Tune in the alphabetical List, insert the new Tune as the new beginning of the alphabetical Linked List

                if (theListAlph == currentTune) {

                    insertNewFirst(newNode, currentTune, theListPop);

                }

                // Inserting the new Tune in all other locations in the alphabetical Linked List

                else    {

                    insertBeforeNotFirst(newNode, currentTune, theListPop);

                }

                temp = 1;

            }

            // The new artist is the same as the tested artist, begin testing the titles of the Tunes lexicographically 

            if (compare == 0)   {

                String testTitle = currentTune.title;
                String newTitle = title;
                int compareTitle = newTitle.compareTo(testTitle);

                // The new title comes before the tested title lexicographically

                if  (compareTitle < 0)  {

                    Tune newNode = new Tune(artistName, title);

                    // If the tested Tune was the first Tune in the alphabetical List, insert the new Tune as the new beginning of the alphabetical Linked List

                    if  (theListAlph == currentTune)    {

                        insertNewFirst(newNode, currentTune, theListPop);

                    }

                    // Inserting the new Tune in all other locations in the alphabetical Linked List

                    else    {

                        insertBeforeNotFirst(newNode, currentTune, theListPop);

                    }

                    temp = 1;

                }

                //The titles are the same
                //The same tune cannot be entered twice

                if  (compareTitle == 0) {

                    temp = 2;

                }

            }       

            // The new tune comes last alphabetically, it will be added to the end of the List

            if  (currentTune.nextAlph == null && temp == 0) {

                Tune newNode = new Tune(artistName, title);
                currentTune.nextAlph = newNode;
                newNode.prevAlph = currentTune;
                currentTune = theListPop;
                while   (currentTune.nextPop != null)   {

                    currentTune = currentTune.nextPop;

                }

                currentTune.nextPop = newNode;
                newNode.prevPop = currentTune;
                temp = 1;

            }

            currentTune = currentTune.nextAlph;

        }

    }

    return temp;

}

【问题讨论】:

  • 你在什么操作系统上运行?
  • 您正在打印“关闭服务器”,但您是否正在关闭任何东西?
  • 在代码的更下方,各个线程的 IO 以及线程本身都被关闭。它看起来像: // 关闭 IO 和 clientThread in.close(); out.close();传入连接.close();

标签: java client bufferedreader server printwriter


【解决方案1】:

尝试在out.println("2"); 之后添加out.flush();

【讨论】:

  • 试过了,导致线程捕获空指针异常。不确定这是否意味着我的线程编码错误或者这不是解决方案。
  • 好的。所以至少我们知道服务器现在正在处理请求。是吗?
  • 是的,我相信。正如我所说,我已经用一个 telnet 客户端自己输入“2”对其进行了测试,它在那里工作正常。所以我相信它只是与 readline();但我是新手,所以我真的不能确定。
  • 让我们看看堆栈跟踪。
  • 线程“Thread-1”中的异常 java.lang.NullPointerException at TuneList.listAlphabetically(TuneList.java:184) at clientThread.run(LikeTunesServer.java:290) 你的意思是这样吗?这就是我粗略搜索堆栈跟踪是什么的意思;我以前从未使用过它。无论如何, Tunelist.java 的第 184 行是这样的: result = currentTune.returnTune();... 返回一个字符串。而服务器线程的第290行是: String result = new String(LikeTunesServer.tl.listAlphabetically());对不起,如果我错过了什么。并感谢您尝试帮助我:)
猜你喜欢
  • 2023-03-28
  • 2012-07-02
  • 1970-01-01
  • 1970-01-01
  • 2017-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-23
相关资源
最近更新 更多