网络_套接字_java

Posted S-Mustard

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了网络_套接字_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\\r\\n").append("Host:"+ "www.baidu.com" + "\\r\\n").append("\\r\\n");
            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+"\\r\\n";
                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();
            }
        }
    }
}

 

 

测试结果如下

 

 

 

 

以上是关于网络_套接字_java的主要内容,如果未能解决你的问题,请参考以下文章

iOS 上的 VoIP 套接字 - 未收到通知

Linux应用学习_网络开发

Python_网络编程_socket()

Linux网络学习_socket套接字

网络编程之TCP客户端开发和TCP服务端开发

Python网络编程_TCP(简略版)