zoukankan      html  css  js  c++  java
  • 网络_套接字_java

    1  由于(https://www.cnblogs.com/S-Mustard/p/11924227.html)讲到通过telnet访问百度首页,现在通过java代码来实现访问百度服务,获取首页信息。

           try(Socket s=new Socket("www.baidu.com",80);
                Scanner in =new Scanner(s.getInputStream(),"UTF-8");
                BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));){
                StringBuffer sb = new StringBuffer();
                sb.append("GET https://www.baidu.com HTTP/1.1
    ").append("Host:"+ "www.baidu.com" + "
    ").append("
    ");
                out.write(sb.toString());
                out.flush();
                while(in.hasNextLine()){
                    System.out.println(in.nextLine());
                }
            }

    2 java实现套接字服务器,由telnet工具建立连接,发送消息

                Boolean done=false;
                ServerSocket s =new ServerSocket(8189);
                Socket incoming=s.accept();// 此时如果telnet不发送任何的连接,即程序会停止在此处,不往下执行,即阻塞状态
    
                InputStream inStream=incoming.getInputStream();
                OutputStream outStream=incoming.getOutputStream();
    
                Scanner in=new Scanner(inStream,"UTF-8");
                PrintWriter out=new PrintWriter(new OutputStreamWriter(outStream,"UTF-8"),true);
    
    while(!done && in.hasNextLine()) {//in.hasNextLine()是阻塞状态,如果telnet客户端不进行任何的输入 String line=in.nextLine(); out.println("echo:"+line); if(line.trim().equals("bye")) done=true; }

    启动程序后,用telnet访问

    1) 不进行任何的操作,程序阻塞

    2) 进行连接,输入telnet localhost 8189,不进行任何的输入文字,程序会阻塞

    3) 输入文字,进入循环内部,一次循环结束,如果不继续输入文字,又是阻塞状态

    4) 输入bye,进入循环内部,执行到done=true,结束整个程序,ServerSocket不存在,所以会看到遗失对主机的连接。

     3 java写客户端和服务器端,客户端访问服务器端

    客户端

            try(Socket s=new Socket("localhost",8189);
                Scanner in =new Scanner(s.getInputStream(),"UTF-8");
                BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));){
    
                Scanner sysin=new Scanner(System.in);
                System.out.println("请输入:");
                while(sysin.hasNextLine()) {
                    String line = sysin.nextLine();
                    line=line+"
    ";
                    System.out.println("输入:"+line);
                    out.write(line);
                    out.flush();
                    System.out.println(in.nextLine());
                }
            }

    服务器端

                Boolean done=false;
                ServerSocket s =new ServerSocket(8189);
                Socket incoming=s.accept();
    
                System.out.println("===============");
                InputStream inStream=incoming.getInputStream();
                OutputStream outStream=incoming.getOutputStream();
    
                Scanner in=new Scanner(inStream,"UTF-8");
                PrintWriter out=new PrintWriter(new OutputStreamWriter(outStream,"UTF-8"),true);
    
                while(!done && in.hasNextLine()) {
                    String line=in.nextLine();
                    System.out.println("回传:"+line);
                    out.println("echo:"+line);
                    if(line.trim().equals("bye")) done=true; 
                }

     分别启动客户端和服务器端,在客户端的控制台输入字符,可以看到服务器的echo,当客户端输入bye后,服务器端会停止运行,此时客户端程序因为连不上服务器端会报错停止。

    客户端结果

    服务器端结果

    4 服务器支持多客户端编程

    当我们尝试再打开一个cmd用telnet连接server时,发现根本得不到反应,只有第一个cmd才能得到反应,而且当第一个cmd关闭连接时,in.hasNextLine()为false

    ,整个程序被停止。

    如何让我们写的程序能支持多个客户端,就是创建多个Socket incoming=s.accept();来对我们的多个客户端做出反应。

    第一想法是用for循环创建多个Socket ,但是有一个问题,这是排队的形式,只有当第一个客户端关闭时,第二个客户端的输入才能得到第二个服务器的反应。也就是当第一个循环体内代码走完时,才能进入第二个循环体内,第二个循环体内的服务器端才能为第二个客户端服务。

    如下代码做测试,启动服务,用telnet工具访问服务。

    
                ServerSocket s =new ServerSocket(8189);
                for(int i=0;i<2;i++){
    Boolean done=false; Socket incoming
    =s.accept(); System.out.println("==============="); InputStream inStream=incoming.getInputStream(); OutputStream outStream=incoming.getOutputStream(); Scanner in=new Scanner(inStream,"UTF-8"); PrintWriter out=new PrintWriter(new OutputStreamWriter(outStream,"UTF-8"),true); while(!done && in.hasNextLine()) { String line=in.nextLine(); System.out.println("回传:"+line); out.println("echo:"+line); if(line.trim().equals("bye")) done=true; } System.out.println("停止运行"); }

    那么如上是实现不了为多个客户端同时服务的,就想到线程的方式,可以同时为多个客户端服务。

    public class Test {
        public static void main(String[] agrs) throws IOException {
                ServerSocket s =new ServerSocket(8189);
                for(int i=0;i<2;i++){// 先支持两个客户端的访问
                    new Thread(new ImplRunnable(s)).start();
                }
        }
    
        static class ImplRunnable implements Runnable{
            private ServerSocket s ;
            public ImplRunnable(ServerSocket s){
                this.s=s;
            }
    
            @Override
            public void run() {
                try{
                    Boolean done=false;
                    Socket incoming=s.accept();
                    System.out.println("===============");
                    InputStream inStream=incoming.getInputStream();
                    OutputStream outStream=incoming.getOutputStream();
                    Scanner in=new Scanner(inStream,"UTF-8");
                    PrintWriter out=new PrintWriter(new OutputStreamWriter(outStream,"UTF-8"),true);
                    while(!done && in.hasNextLine()) {
                        String line=in.nextLine();
                        System.out.println("回传:"+line);
                        out.println("echo:"+line);
                        if(line.trim().equals("bye")) done=true;
                    }
                    System.out.println("停止运行");
                }catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    测试结果如下

  • 相关阅读:
    获取exe和dll里面的资源
    [C++] 反编译器
    再一次利用with as 优化SQL
    编码指南:寻找科学中的艺术
    对手机支付安全机制的思考
    用adblock过滤页面上固定位置的悬浮窗
    git卡在Resolving deltas 100%的解决办法
    十字路口的程序员
    hdu 2555
    hdu 1864
  • 原文地址:https://www.cnblogs.com/S-Mustard/p/11938744.html
Copyright © 2011-2022 走看看