Java学习day23--网络编程

网页编程 : 关注上层应用

网络编程 : 关注底层数据的传输

IP地址 : 定位网络中的节点...(电脑,手机....)

端口号 : 区分软件

URL : 同一资源定位符

传输层协议 : (标准,合同,规范)

UDP : 邮寄包裹|写信 不安全,协议简单,开销小,效率高 大小限制一般不超过60k

TCP : 打电话 基于连接 安全,效率低 没有大小限制

IP : 定位网络中的节点...(电脑,手机....)

IPV4 4个字节32位 IPV6128位

特殊的IP :

192.168.0.0~192.168.255.255 非注册IP,供组织内部使用的IP

127.0.0.1 本地IP

localhost : 本地

IP 与 域名

DNS解析器 : 做域名与IP直接解析问题

java.net包下:InetAddress

端口 : 件区分软

  • 2个字节 0~65535表示端口号

  • 同一协议下端口号不能冲突

  • 8000称为预留端口号,建议自己设置端口号为8000以上

  • 常见的端口号 :

80 : http

8080 : tomcat

3306 : mysql

1521 : oracle

InetSocketAddress :此类实现IP套接字地址(IP地址+端口号)

Socket : 套接字

传输层为应用层开辟的一个小口子(面向Socket编程,不同的传输层协议对Socket的实现不同)

UDP协议实现 :

两端平等 : 发送端 接口端

UDP协议下数据传输基于字节数组

DatagramSocket

DatagramSocket(int port) 构造一个数据报套接字并将其绑定到本地主机上的指定端口。

void receive(DatagramPacket p) 从此套接字接收数据报包。

void send(DatagramPacket p) 从此套接字发送数据报包。

DatagramPacket : 该类表示数据报包。

UDP协议下基本流程 : 发送端

1.定义发送端

2.准备数据

3.打包

4.发送

5.关闭

        //1.定义我是发送端
        DatagramSocket sendSocket = new DatagramSocket(9999);
        //2.准备数据
        byte[] arr = "哈啰".getBytes();
        //3.打包
        DatagramPacket packet = new DatagramPacket(arr,0,arr.length,new InetSocketAddress("127.0.0.1",8888));
        //4.发送
        sendSocket.send(packet);
        //5.关闭
        sendSocket.close();

UDP协议下基本流程 : 接收端

1.定义接收端

2.准备包裹,用来接收数据

3.接收数据

4.处理数据

5.关闭

        //1.定义接收端
        DatagramSocket receiveSocket = new DatagramSocket(8888);
        //2.准备包裹,用来接收数据
        byte[] arr = new byte[1024];
        DatagramPacket packet = new DatagramPacket(arr,0,arr.length);
        //3.接收数据
        receiveSocket.receive(packet);
        //4.处理数据
        //byte[] getData() 返回数据缓冲区。
        byte[] newArr = packet.getData();
        //int getLength() 返回要发送的数据的长度或接收的数据的长度。
        int len = packet.getLength();
        System.out.println(new String(newArr,0,len));
        //5.关闭
        receiveSocket.close();

Tcp协议实现 :

TCP : 基于连接的,类似打电话, 安全,效率低 没有大小限制 基础3次握手建立连接 几次挥手断开连接

协议下两端是不平等的 ,客户端 服务器端

tcp协议下数据传输基于IO流

TCP协议下实现基本流程 :

客户端

1.定义我是客户端 Socket该类实现客户端套接字(也称为“套接字”)。 套接字是两台机器之间通信的端点。

Socket(String host, int port) 参数ip+端口 指的是服务器的IP+端口

2.准备数据

3.获取输出流,向服务器发送数据

4.刷出

5.关闭

        //1.定义客户端
        Socket client = new Socket("localhost",8989);
        System.out.println("连接建立起来了....");
        //2.准备数据
        String msg = "good good study,day day up!!!";
        //3.获取输出流,向服务器发送数据
        DataOutputStream os = new DataOutputStream(client.getOutputStream());
        os.writeUTF(msg);
        //4.刷出
        os.flush();
        //5.关闭
        os.close();
        client.close();
    }

服务器端

1.定义我是服务器 ServerSocket该类实现服务器套接字。

2.阻塞式监听

3.获取输入流,读取客户端发送的数据

4.处理数据

5.关闭

        //1.定义服务器 ServerSocket
        ServerSocket server = new ServerSocket(8989);
        //2.阻塞式监听 Socket accept() 侦听对此套接字的连接并接受它。
        Socket client = server.accept();
        System.out.println("与一个客户端建立连接了.............");
        //3.获取输入流,读取客户端发送的数据
        DataInputStream is = new DataInputStream(client.getInputStream());
        String msg = is.readUTF();
        //4.处理数据
        System.out.println(msg);
        //5.关闭
        is.close();
        client.close();
        server.close();
    }
TCP协议下实现双向登录流程 :

客户端

1.定义我是客户端

2.键盘输入接收用户输入的登录信息 username=zhangsan&password=123

3.获取输出流,向服务器发送数据

4.刷出

5.获取输入流,读取服务器响应的结果

6.处理结果

7.关闭

        //1.定义客户端
        Socket client = new Socket("localhost",8989);
        System.out.println("连接建立起来了....");
        //2.准备数据
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        System.out.println("请输入用户名:");
        String username = bf.readLine();
        System.out.println("请输入密码:");
        String password = bf.readLine();
        //3.获取输出流,向服务器发送数据
        DataOutputStream os = new DataOutputStream(client.getOutputStream());
        os.writeUTF("username="+username+"&password="+password);
        //4.刷出
        os.flush();
        //5.获取输入流,读取服务器响应的结果
        DataInputStream is = new DataInputStream(client.getInputStream());
        String result = is.readUTF();
        //6.处理结果
        System.out.println(result);
        //7.关闭
        is.close();
        os.close();
        bf.close();
        client.close();

服务端

1.定义我是服务器

2.阻塞式监听

3.获取输入流,读取客户端发送的数据

4.处理数据

校验用户输入的登录信息是否正确(admin 1234)

5.获取输出流,将结果响应给客户端

6.刷出

7.关闭

        //1.定义服务器 ServerSocket
        ServerSocket server = new ServerSocket(8989);
        //2.阻塞式监听
        Socket client = server.accept();
        System.out.println("与一个客户端建立连接了.............");
        //3.获取输入流,读取客户端发送的数据
        DataInputStream is = new DataInputStream(client.getInputStream());
        String msg = is.readUTF();
        //4.处理数据
        //1)校验方式
        /*if("username=admin&password=1234".equals(msg)){
            System.out.println("登录成功");
        }else{
            System.out.println("用户名或密码错误");
        }*/
        //2)校验方式
        String uname=null;
        String upwd=null;
        String[] arr = msg.split("&");
        for(String str:arr){
            String[] arr2 = str.split("=");
            if("username".equals(arr2[0])){
                uname = arr2[1];
            }else if("password".equals(arr2[0])){
                upwd = arr2[1];
            }
        }
        //5.获取输出流,将结果响应给客户端
        DataOutputStream os = new DataOutputStream(client.getOutputStream());
        if("admin".equals(uname) && "1234".equals(upwd)){
            os.writeUTF("登录成功");
        }else{
            os.writeUTF("用户名或密码错误");
        }
        //6.刷出
        os.flush();
        //7.关闭
        os.close();
        is.close();
        client.close();
        server.close();
TCP协议下实现多用户登录流程 :

服务端

服务器端能够实现多多个客户端做响应

重复执行某段代码可以使用循环,但是多个客户端只能排队登录

        //1.定义我是服务器 ServerSocket
        ServerSocket server = new ServerSocket(8989);
        //2.阻塞式监听
        boolean flag = true;
        while(flag){
            Socket client = server.accept();
            System.out.println("与一个客户端建立连接了.............");
            //3.获取输入流,读取客户端发送的数据
            DataInputStream is = new DataInputStream(client.getInputStream());
            String msg = is.readUTF();
            //4.处理数据
            String uname=null;
            String upwd=null;
            String[] arr = msg.split("&");
            for(String str:arr){
                String[] arr2 = str.split("=");
                if("username".equals(arr2[0])){
                    uname = arr2[1];
                }else if("password".equals(arr2[0])){
                    upwd = arr2[1];
                }
            }
            //5.获取输出流,将结果响应给客户端
            DataOutputStream os = new DataOutputStream(client.getOutputStream());
            if("admin".equals(uname) && "1234".equals(upwd)){
                os.writeUTF("登录成功");
            }else{
                os.writeUTF("用户名或密码错误");
            }
            //6.刷出
            os.flush();
            //7.关闭
            os.close();
            is.close();
            client.close();
        }
        server.close();

服务端

利用多线程实现,监听到一个客户端就开启一个线程提供服务

        //1.定义服务器 ServerSocket
        ServerSocket server = new ServerSocket(8989);
        //2.阻塞式监听
        boolean flag = true;
        while(flag){
            Socket client = server.accept();
            System.out.println("与一个客户端建立连接了.............");
            //开启线程对client提供服务
            new Thread(new Channel(client)).start();
        }
        server.close();
    }

    static class Channel implements Runnable{
        Socket client = null;
        DataInputStream is = null;
        DataOutputStream os = null;

        public Channel(Socket client) {
            this.client = client;
            try {
                is = new DataInputStream(client.getInputStream());
                os = new DataOutputStream(client.getOutputStream());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        //读取数据
        public String read(){
            String msg = null;
            try {
                msg = is.readUTF();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return msg;
        }

        //写出
        public void write(String msg){
            try {
                os.writeUTF(msg);
                //6.刷出
                os.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        //关闭
        public void close(){
            if(os!=null){
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            };
            if(is!=null){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            };
            if(client!=null){
                try {
                    client.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            };
        }

        @Override
        public void run() {
            //3.获取输入流,读取客户端发送的数据
            String msg = read();
            //4.处理数据
            String uname=null;
            String upwd=null;
            String[] arr = msg.split("&");
            for(String str:arr){
                String[] arr2 = str.split("=");
                if("username".equals(arr2[0])){
                    uname = arr2[1];
                }else if("password".equals(arr2[0])){
                    upwd = arr2[1];
                }
            }
            //5.获取输出流,将结果响应给客户端
            if("admin".equals(uname) && "1234".equals(upwd)){
                write("登录成功");
            }else{
                write("用户名或密码错误");
            }
            //7.关闭
            close();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值