-1

我是 java.net 的新手,正在尝试制作一个简单的客户端-服务器应用程序。这是服务器代码:

public class Consumer extends Thread{

    public Socket s;
    int num;

    public Consumer(int num, Socket s){
        this.num = num;
        this.s = s;

        setDaemon(true);
        setPriority(NORM_PRIORITY);
        start();
    }

    public static void main(String args[]){
        try {
            int i = 0;

            ServerSocket server = new ServerSocket(3128, 0, InetAddress.getByName("localhost"));

            System.out.println("server started");
            while (true){
                new Consumer(i, server.accept());
                i++;
            }
        } catch (Exception e){

        }
    }

    public void run(){
        try {
            InputStream is = s.getInputStream();
            OutputStream os = s.getOutputStream();

            byte buf[] = new byte[64*1024];
            int r = is.read(buf);

            String data = new String(buf, 0, r);

            data = "" +num+": " +"\n" + data;

            os.write(data.getBytes());

            s.close();
        } catch (Exception e){
            System.out.println("init error: " + e);
        }
    }

}

当我启动它时 - 没有发生任何不好的事情,但是当我从某个客户端发送 smth 时,我得到以下信息:

init error: java.lang.StringIndexOutOfBoundsException: String index out of range: -1

如何解决?

4

4 回答 4

2

可能你的

int r = is.read(buf);

正在返回-1,因此此代码失败:

String data = new String(buf, 0, r);

检查流的结尾:

int bytesRead;
while( (bytesRead = in.read(buf)) != -1 ) {
 // then create a String from the byte[]
}

查看InputStream#read(byte[] b)的文档

回报:

读入缓冲区的总字节数,如果由于到达流的末尾而没有更多数据,则为 -1。

以及String(byte[] bytes,int offset,int length)的文档

抛出:

IndexOutOfBoundsException - 如果偏移量和长度参数索引字符超出字节数组的范围

于 2013-07-15T11:36:23.900 回答
1

当您从输入流中读取数据时,您知道当read返回 -1 时您已经到达了流的末尾。看起来这就是这里发生的情况: r 显示为 -1,因为没有要读取的数据,然后程序继续尝试创建一个字符数为负数的字符串。

您应该始终检查函数的返回值是否存在错误情况:

        int r = is.read(buf);

        if (r < 0) return; /* end of stream was reached */

此外,在处理异常时,您应该打印堆栈跟踪。堆栈跟踪告诉您异常发生在程序的哪一行。如果没有这些信息,您必须通过猜测开始调试过程。

    } catch (Exception e){
        System.out.println("init error: " + e);
        e.printStackTrace();
    }
于 2013-07-15T11:39:32.083 回答
1

我遇到了您的问题。在您粘贴的链接中,您需要使用命令行参数 test1、test2、abc、mno 运行程序 SampleClient。尝试按照链接中的说明运行:

java SampleClient test1
java SampleClient test2
...
java SampleClient testN

实际上你的程序没有运行,因为它没有读取数据,因为它没有参数所以

int r = is.read(buf);

正在返回 -1 因此异常。

于 2013-07-15T11:58:29.043 回答
0

您的错误是您在没有传递命令行参数的情况下启动了程序。

你应该从错误中吸取教训。将来仔细研究系统的输入和输出。

此外,您应该从异常中获取更多信息,因此堆栈跟踪是您的朋友。

最后,IDE 会对您有所帮助。例如,您可以下载 NetBeans 或 Eclipse,它们将大大简化您作为开发人员的生活。

于 2013-07-15T14:41:44.587 回答