javasocket错误readLine()

我写了个socket服务端,但是编译出错,说第26行错了,我也不知道怎么改
请问哪错了,谢谢

import java.awt.*;
import java.net.*;
import java.io.*;

public class a {
    public static void main(String[] args) throws InterruptedIOException {
        try {//建立socket
            Frame a = new Frame("serversocket");
            a.setVisible(true);
            a.setSize(50, 50);
            a.setBounds(0, 0, 100, 100);
            ServerSocket s1 = new ServerSocket(8000);//注:如果服务器在内网需要端口映射
            Socket x = s1.accept();
            System.out.println("服务已开启");
            //读取客户端的信息
            BufferedReader g = new BufferedReader(new InputStreamReader(x.getInputStream(), StandardCharsets.UTF_8));
            String str ;
            while ((str = g.readLine())!=null) {//就是这里
                System.out.println(str);
            }
                System.out.println(str);
                Button a1 = new Button(str);
                a1.setBounds(0, 0, 500, 500);
                a.add(a1);

                x.close();
                s1.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Java API网站是个好东西。这个 BufferedReader 的readLine方法在API网站上的解释是这样的:

img


可以据此推断,如果这个readLine要想出错,那一定是出现了IO错误。这种错误大多数时候是由于信息不存在导致的。观察你的源代码。可以发现,信息来源是x.getInputStream()

img


可以发现。这个方法本身也会抛出IO异常。所以很可能这个IO错误是从这里传递过来的。
我们继续研究API文档。这里注意一下这两句话:

img


img


还记得读取调用有几次吗?除了这一次,后面还会通过readLine方法进行一次读取。也就是说,如果”如果套接字上没有缓冲的字节,或者所有缓冲的字节都被读取消耗了“那么后面readLine便会产生IO异常。同样,这两句话都把错误的矛头指向了套接字。然后我们再来研究你的代码。很明显,这个Socket的对象变量x来自ServerSocket对象s1方法accept()所返回的值。我们继续用API文档查询这个方法与ServerSocket的构造器

img


img


很明显。对这个IO错误进行溯源,发现这个错误产自这个ServerSocket的构造器,然后经过一顿传递,最后被readLine抛出。这里的意思是当打开套接字错误时发生IO错误。那么你就应该考虑考虑8000端口是否被占用的问题了。
OK,以上就是我对你源码的分析了。我不知道我的分析是否正确,但是我尽力了。学会使用API文档,有时候确实能帮你一把。