java BIO实例——ServerSocket、Socket编程

在使用传统的ServerSocket和Socket的时候很多时候程序是会阻塞的比如serversocket.accept() , socket.getInputStream().read() 的时候都会阻塞

  • accept()方法除非等到客户端socket的连接或者被异常中断否则会一直等待下去
  • read()方法也是如此除非在输入流中有了足够的数据否则该方法也会一直等待下去知道数据的到来

在ServerSocket与Socket的方式中服务器端往往要为每一个客户端连接(socket)分配一个线程,而每一个线程都有可能处于长时间的阻塞状态中而过多的线程也会影响服务器的性能在JDK1.4引入了非阻塞的通信方式NIO这样使得服务器端只需要一个线程就能处理所有客户端socket的请求

 

【实例1:单机版】

1Server

public class Server{

 

publicstatic void main(String[] args) throws IOException {

//创建一个ServerSocket在端口4700监听客户请求

ServerSocketserver = new ServerSocket(5678);

/**

 * 使用accept()阻塞等待客户连接,有客户请求到来则产生一个Socket对象,并继续执行

 */

Socketsocket = server.accept();

 

//由Socket对象得到输入流,并构造相应的BufferedReader对象

BufferedReaderin = new BufferedReader(new InputStreamReader(socket.getInputStream())); 

//由Socket对象得到输出流,并构造PrintWriter对象

             PrintWriter out =new PrintWriter(socket.getOutputStream());

       

            while (true) {

                 //阻塞读取客户端发送的数据、并向标准输出

            String str = in.readLine(); 

            System.out.println(str);

           

            //向客户端输出字符,并刷新输出流,使Client马上收到该字符串

            out.println("hasreceive...."); 

            out.flush(); 

           

           

            if(str.equals("end")) 

                break; 

          }

       

        out.close();//关闭socket输出流

        in.close();//关闭socket输入流

        socket.close();//关闭socket

        server.close();//关闭serverSocket

}

}

2Client

public class Client{

staticSocket server; 

 

publicstatic void main(String[] args) throws Exception{

//向本机的5678端口发出客户请求

      server= new Socket(InetAddress.getLocalHost(), 5678);

 

//由Socket对象得到输入流,并构造相应的BufferedReader对象

        BufferedReader in = newBufferedReader(new InputStreamReader(server.getInputStream()));

        //由Socket对象得到输出流,并构造PrintWriter对象

        PrintWriter out = newPrintWriter(server.getOutputStream());

       

        //由系统标准输入设备构造BufferedReader对象

        BufferedReader wt = newBufferedReader(new InputStreamReader(System.in)); 

        while (true) {

               //从标准输入读取

            String str = wt.readLine();

           

            //向服务器端输出字符,并刷新输出流,使server马上收到该字符串

            out.println(str); 

            out.flush();

           

           

            if (str.equals("end")){ 

                break; 

            } 

           System.out.println(in.readLine()); 

        }

       

        out.close();//关闭Socket输出流

        in.close();//关闭Socket输入流

        server.close();//关闭Socket

 

}

}

说明:上面代码,只能有一个客户端链接到服务器。一旦有一个客户端链接到了服务器,服务器代码就会一直处在while死循环中,和客户端通信,直到客户端退出。

 

【实例2:多线程版】

1ServerThread

public classServerThread extends Thread{

privateSocket socket; 

 

    public ServerThread(Socket s) { 

        this.socket = s; 

    }

   

    public void run() { 

        try {

               //构造socket的输入流

            BufferedReader in = newBufferedReader(new InputStreamReader(socket.getInputStream()));

            //根据socket构造输出流

            PrintWriter out = newPrintWriter(socket.getOutputStream()); 

            // Mutil User but can'tparallel 

 

            while (true) {

                   //读取客户端输入流中内容

                String str =in.readLine(); 

                System.out.println(str);

               

                //向客户端输出

                out.println("hasreceive...."); 

                out.flush();

               

                if(str.equals("end")) 

                    break; 

            }

            out.close();

            in.close();

            socket.close(); 

        } catch (IOException ex) { 

        } finally {

               

        } 

    } 

 

publicstatic void main(String[] args) throws IOException {

ServerSocketserver = new ServerSocket(5678);

while(true) { 

            //每一个客户端连接(server.accept())分配一个线程来处理

               ServerThread mc = new ServerThread(server.accept()); 

            mc.start(); 

        }

}

}

2)客户端代码同上;

3)说明:

  • 服务器一直处在死循环中,为每一个客户端连接分配一个线程,所以服务器可以接收多个客户端的请求;
  • 由于server.accept()read等方法是阻塞的,所以在每一个线程都有可能处于长时间的阻塞状态,这样当客户端大量连接服务器时,就会积累大量的线程(线程中也是一时半会无法执行结束);
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

赶路人儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值