欢迎光临散文网 会员登陆 & 注册

java套接字Socket、ServerSocket

2022-09-07 08:56 作者:虚云幻仙  | 我要投稿

/**
* 测试ServerSocket类和Socket类
* Socket为传输层供给应用层的编程接口,用于应用层与传输层之间的数据通信
* Socket类使用TCP协议,客户端向服务端发出连接请求,经过三次握手后客户端和服务端不再有区别,都可收发数据
* ServerSocket为服务端,“请求-响应”模式需要先运行服务端监听端口,再通过客户端进行访问
*/

public class TestServerSocket extends Thread{
   public void server(){
       //创建服务器线程
       ServerSocket ss=null;
       Socket client=null;
       BufferedReader br = null;
       BufferedOutputStream bos = null;
       try {
           ss = new ServerSocket(8888);
           //创建服务端,构造器传参端口号port,设定为8888端口,这时服务端尚未运行
           client = ss.accept();
           //.accept()方法监听端口,线程进入阻塞状态,直到accept接收到连接,返回Socket对象,这个对象象征客户端,通过这个对象来与客户端收发数据
           br = new BufferedReader(new InputStreamReader(client.getInputStream()));
           //.getInputStream()返回输入流,数据源为客户端通过输出流发送的内容,如果是http请求,发送的内容包括请求首行、请求头、空行、请求体
           for (String text = br.readLine();text!=null;text = br.readLine()){
               System.out.println(text);
               //使用缓冲字符流输出整行内容,当读完客户端当前发送的所有内容后.read()会继续阻塞等待接收新的内容,这使得.readLine()并不会返回null。只有当客户端关闭输出流时.readLine()才会返回null表示读完了
           }
           bos = new BufferedOutputStream(client.getOutputStream());
           //.getOutputStream()返回字节输出流,用于向客户端发数据,在建立连接之后双方都可以收和发
           bos.write("HTTP/1.1 200 OK\r\n\r\nHello World\r\n".getBytes());
           //字节缓冲流发送字节数组
           bos.flush();
           //数据写完必须要flush()
           client.shutdownOutput();
           //发送完数据关闭输出流,以解除接收方.read()造成的阻塞
       } catch (IOException e) {
           throw new RuntimeException(e);
       }finally {
           if (br != null) {
               try {
                   br.close();
               } catch (IOException e) {
                   throw new RuntimeException(e);
               }
           }
           if (client != null) {
               try {
                   client.close();
               } catch (IOException e) {
                   throw new RuntimeException(e);
               }
           }
           if (ss != null) {
               try {
                   ss.close();
               } catch (IOException e) {
                   throw new RuntimeException(e);
               }
           }
           if (bos != null) {
               try {
                   bos.close();
               } catch (IOException e) {
                   throw new RuntimeException(e);
               }
           }
       }
   }

   public void client(){
       //创建客户端线程
       Socket socket=null;
       PrintWriter pw =null;
       BufferedInputStream bis = null;
       try {
           socket = new Socket("127.0.0.1",8888);
           //创建Socket对象,需要指定域名/ip地址和端口号,构造器返回的对象象征服务端,通过这个对象即可与服务端收发数据
           pw = new PrintWriter(socket.getOutputStream(),true);
           //.getOutputStream()返回字节输出流,通过这个字节输出流可以向服务端发送数据
           //PrintWriter作为处理流包裹字节流时设定boolean autoFlush=true会套缓冲流并且自动flush
           //PrintWriter构造器中不设定autoFlush时默认false,且autoFlush只有在println自动换行中生效,使用print()不会flush

           pw.println("GET / HTTP/1.1\r\n\r\n");
           socket.shutdownOutput();
           //发送完数据需要关闭输出流 ,这样对方才能read()=-1,一旦关闭输出流无法再打开
           bis = new BufferedInputStream(socket.getInputStream());
           //接收服务器返回的数据
           int b;
           while ((b=bis.read())!=-1){
               //也可以规定发送一段符号代表数据结尾,或者数据开头标明字节数,读到一定数量结束循环
               System.out.write(b);
           }
       } catch (IOException e) {
           throw new RuntimeException(e);
       }finally {
           if (pw != null) {
               pw.close();
           }
           if (socket != null) {
               try {
                   socket.close();
               } catch (IOException e) {
                   throw new RuntimeException(e);
               }
           }
           if (bis != null) {
               try {
                   bis.close();
               } catch (IOException e) {
                   throw new RuntimeException(e);
               }
           }
       }
   }

   boolean isServer;
   //构造器区分客户端和服务端

   public TestServerSocket(String name, boolean isServer) {
       super(name);
       this.isServer = isServer;
   }

   @Override
   public void run() {
       if (isServer){
           server();
       }else {
           client();
       }
   }

   public static void main(String[] args) {
       new TestServerSocket("服务端",true).start();
       try {
           Thread.sleep(300);
       } catch (InterruptedException e) {
           throw new RuntimeException(e);
       }
       new TestServerSocket("客户端",false).start();

       //结果:服务端线程打印GET / HTTP/1.1
       //客户端打印HTTP/1.1 200 OK  Hello World


   }
}

java套接字Socket、ServerSocket的评论 (共 条)

分享到微博请遵守国家法律