Java.net服务器示例不起作用

时间:2013-07-15 11:32:40

标签: java sockets

我是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 个答案:

答案 0 :(得分: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 - 如果offset和length参数索引字节数组边界之外的字符

答案 1 :(得分: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();
    }

答案 2 :(得分:1)

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

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

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

int r = is.read(buf);

返回-1因此异常。

答案 3 :(得分:0)

您的错误是您已经启动了程序而没有传递命令行参数。

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

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

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