使用传递给线程的Socket时“套接字是否已关闭”异常?

时间:2013-08-03 11:20:55

标签: java multithreading sockets

我正在创建一个简单的Web服务器,每次客户端连接时我都会生成一个新线程。然后,我需要使用BufferedOutputStream发送响应(因为HTTP协议在行的末尾需要/ r / n)。 这是我的代码:

class HttpServer{
    public static void main(String args[]){
        ServerSocket ss = null;
        int port = 40000;

        try{
            if(args.length > 0){
                port = Integer.parseInt(args[0]);
            }

            ss = new ServerSocket(port);

            while(true){
                Socket client = ss.accept();
                User user = new User(client);
                user.start();
            }
        }
        catch(Exception e){
                System.err.println(e.getMessage());
        }
    }
}

我的用户类:

class User extends Thread{

        Socket client;

        public User(Socket s){
            client = s;
        }

        public void run(){
            try{
                BufferedOutputStream bos = new BufferedOutputStream(client.getOutputStream());

                println(bos, "Hello World");
                bos.close();

                client.close();
            }
            catch(Exception e){
                    System.err.println(e.getMessage());
            }
        }

        private void println(BufferedOutputStream bos, String s) throws IOException { 
            String news = s + "\r\n"; 
            byte[] array = news.getBytes(); 
            for(int i=0; i<array.length; i++){
                bos.write(array[i]);
            }
            return;
        }
    }

当我尝试创建BufferedOutputStream时会出现问题;它给了我一个“Socket is closed”错误,我不明白为什么。

非常感谢任何帮助。

谢谢!

这是不起作用的代码:

class User extends Thread{

    Socket client;

    public User(Socket s){
        client = s;
    }

    public void run(){
        try{
            System.out.println("Address: " + client.getInetAddress().toString());

            BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()));

            String line;
            Boolean first = true;
            while(!((line = reader.readLine()).equals(""))){
                if(first)
                    System.out.println(line.split(" ")[1]);
                first = false;
            }
            reader.close();

            BufferedOutputStream bos = new BufferedOutputStream(client.getOutputStream());
            println(bos, "Hello World");
            bos.close();



            // Close socket
            client.close();
        }
        catch(Exception e){
                System.err.println(e.getMessage());
        }
    }

    private void println(BufferedOutputStream bos, String s) throws IOException { 
        String news = s + "\r\n"; 
        byte[] array = news.getBytes(); 
        for(int i=0; i<array.length; i++){
            bos.write(array[i]);
        }
        return;
    }
}

3 个答案:

答案 0 :(得分:3)

此异常表示关闭了套接字。

关闭输入流或套接字的输出流会关闭另外两个,关闭任何FilterInput / OutputStream / Reader / Writer会关闭它正在过滤的流/读取器/写入器。

答案 1 :(得分:-1)

据我所知,您的代码没有问题。操作系统或浏览器似乎更有可能以某种方式限制对服务器的访问。

答案 2 :(得分:-1)

Socket client = ss.accept();
User user = new User(client);
user.start();

accept调用阻塞等待连接。永远不会创建您的用户线程。您应该创建一个新的User类,为您创建一个新线程,并将您的消息写入服务器。

    public class User extends Thread{

            Socket client;
            int port;
            public User(int p) throws UnknownHostException, IOException{
                port = p;
                client = new Socket(InetAddress.getLocalHost(), 40000);
            }

            public void run(){
                try{
                    BufferedOutputStream bos = new BufferedOutputStream(client.getOutputStream());

                    println(bos, "Hello World");
                    bos.close();

                    client.close();
                }
                catch(Exception e){
                        System.err.println(e.getMessage());
                }
            }

            private void println(BufferedOutputStream bos, String s) throws IOException { 
                String news = s + "\r\n"; 
                byte[] array = news.getBytes(); 
                for(int i=0; i<array.length; i++){
                    bos.write(array[i]);
                }

                return;
            }

            public static void main(String[] args) throws UnknownHostException, IOException {
                User user = new User(4000);
                user.start();
            }
        }

服务器应该只监听传入的连接。(也许可以打印它)

import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;


class HttpServer{
    public static void main(String args[]){
        ServerSocket ss = null;
        int port = 40000;

        try{
            if(args.length > 0){
                port = Integer.parseInt(args[0]);
            }

            ss = new ServerSocket(port);

            while(true){
                Socket client = ss.accept();
                Scanner scanner = new Scanner(client.getInputStream());
                while (scanner.hasNext()) {
                    System.out.println(scanner.nextLine());
                }
            }
        }
        catch(Exception e){
                System.err.println(e.getMessage());
        }
    }
}

将它们作为不同的java进程运行,您应该在服务器端看到hello world。 如果您更改了端口,则可能必须在客户端更改此端口。