JAVA中Socket对象如何重用多次?

试了一下,目前已知的 让socket发送流中的数据 只有一下三种方式

1.shutDown流
2.close流/close socket
3.sendUrgentData

前两种都会socket对象无法再次使用,如果想多次发送数据,只能用第3种。
有更优雅的方式实现socket重用吗?

4个回答

不是的,你得仔细了解一下socket的读写数据机制。
关闭writer和关闭socket的时候,**发现buffer有数据没有写出,会写一遍**,但不是必须关闭流和关闭socket**才会写数据**。
一般是通过输出流的 write()和flush()方法,完成写操作。
想要多次的输出数据,首要条件就是socket不被close和outputStream没有close...
顺便给你贴点代码

 public class TestSocket {

    public static void main(String[] args) throws IOException {
        int port = 10086;
        ServerSocket server = new ServerSocket(port);
        System.out.println("等待与客户端建立连接...");
        while (true) {
            Socket socket = server.accept();
            new Thread(new Task(socket)).start();

        }
        // server.close();
    }

    /**
     * 处理Socket请求的线程类
     */
    static class Task implements Runnable {

        private Socket socket;

        /**
         * 构造函数
         */
        public Task(Socket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {
            try {
                handlerSocket();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        /**
         * 跟客户端Socket进行通信
         * 
         * @throws IOException
         */
        private void handlerSocket() throws Exception {
            for (;;) {
                StringBuilder sb = new StringBuilder();
                InputStream inputStream = socket.getInputStream();
                String temp;
                int index;
                sb.append(inputStream.read());
                System.out.println("Form Cliect[port:" + socket.getPort() + "] 消息内容:" + sb.toString());
                // 回应客户端
                Writer writer = new OutputStreamWriter(socket.getOutputStream(), "UTF-8");
                writer.write(String.format("Hi", socket.getPort()));
                writer.flush();
//              writer.close();
//              socket.close();
            }
        }
    }
}

huruiba
坎特 回复Light_0X0000: 不可以的,socket.getInputStream()是一个阻塞方法,只有读到数据,线程才会往下走。把socket放到list里,也没用的,第一个socket取不到inputstream的数据,就不会往下遍历了。socket和server这套api,在多客户端的时候,是基于一个线程一个socket的模式运行,也叫bio。你也可以去了解一下nio,换一套api,用socketchannel,bytebuffer,selector。这一套可以不用一个线程一个socket
2 年多之前 回复
m0_37741173
bear_0X0000 谢谢了。如果把socket都存到一个集合里,用一个线程来遍历集合(而不是一个socket用一个线程),可行吗
2 年多之前 回复

为什么要重用。你直接保持着socket对象。就可以一直发送数据

baidu_41706873
baidu_41706873 .你直接保持着socket对象,就行了。
2 年多之前 回复

可以一直发的,用printwriter
或者用bufferedwriter然后每条消息要加\r\n结尾并且调用flush

 可以利用多线程, 服务器端不断接收客户端连接, 连接一个就开一个线程处理 客户端的交互,
这里有一个简单的例子,Client端发送消息给Server端,并读取Server端的回复信息;而Server端则先读取Client端的数据,再回复数据。
Server端:

 public class Main {
    public static void main(String[] args) {
        ServerSocket server;
        try {
            server = new ServerSocket(8800);
            System.out.println("Wait for connection...");
            Socket socket = server.accept();
            BufferedInputStream is = new BufferedInputStream(
                    socket.getInputStream());
            byte[] buff = new byte[1024];
            int size;
            while ((size = is.read(buff)) != -1) {
                System.out.println(new String(buff, 0, size));
            }

            OutputStream os = socket.getOutputStream();
            os.write("您好,我是Server端".getBytes());
            os.flush();
            os.close();
            System.out.println("ok,client send over.");
            server.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
Client端:

public class Client {
    public static void main(String[] args) throws Exception 
    {
        Socket s = new Socket("localhost",8800);
        OutputStream os = s.getOutputStream();
        os.write("您好,我是客户端".getBytes());
        os.close();

        InputStream in = s.getInputStream();
        byte[] buff = new byte[1024];
        BufferedInputStream is = new BufferedInputStream(in);
        int size;
        while((size = is.read(buff)) != -1){
            System.out.println(new String(buff,0,size));
        }
        System.out.println("over...");
        s.close();
    }
}
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐