JAVA 网络编程

网页编程 : 关注上层应用

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

一,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 与 域名

域名:例如 ww.yjx.com

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

InetAddress :

java.net

封装计算机的ip地址和DNS(没有端口信息!)

//static InetAddress getLocalHost() 返回本地主机的地址。
InetAddress ip1 = InetAddress.getLocalHost();
System.out.println(ip1);  //HXY/192.168.137.1
System.out.println(ip1.getHostName());
System.out.println(ip1.getHostAddress());
//static InetAddress getByName(String host) 根据主机名称确定主机的IP地址。
InetAddress ip2 = InetAddress.getByName("www.yjxxt.com");
System.out.println(ip2);
System.out.println(ip2.getHostName());
System.out.println(ip2.getHostAddress());

二,端口 : 区分软件

2个字节 0~65535(FFFF)表示端口号

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

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

常见的端口号 :

80 : http

8080 : tomcat

3306 : mysql

1521 : oracle

InetSocketAddress

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

public class Class002_POrt {
    public static void main(String[] args) throws UnknownHostException {
        InetSocketAddress  in1=new InetSocketAddress("localhost",9999);
        System.out.println(in1.getHostName());
        System.out.println(in1.getPort());
        InetAddress ip1=InetAddress.getLocalHost();
        InetSocketAddress in2=new InetSocketAddress(ip1,8888);
        System.out.println(in2.getPort());
        System.out.println(in2.getHostName());
    }
}

三,url

同一资源定位符,互联网中资源的指针

互联网的三大基石 : http html url

url组成 :

协议 : http

域名 : www.baidu.com

端口 : 80

资源 : index.html?username=zhangsan&password=1234#a

一个完整的url http://www.baidu.com:80/index.html?username=zhangsan&password=1234#a

URL类中的一些方法

public class Class003_URL {
    public static void main(String[] args) throws MalformedURLException {
        //URL(String spec)
        URL url = new URL("http://www.baidu.com:80/index.html?username=zhangsan&password=1234#a");
        System.out.println(url);
        System.out.println(url.getProtocol());//访问协议
        System.out.println(url.getHost());//访问域名
        System.out.println(url.getPort());//访问端口号
        System.out.println(url.getPath());//访问当前进入的路径
        System.out.println(url.getFile());//访问完整文件对象
        System.out.println(url.getQuery());//访问查询部分
        System.out.println(url.getRef());//访问引用
    }
}

四,传输层协议

网络分层模型

Socket : 套接字

  • 传输层为应用层开辟的一个小口子

  • 面向Socket编程,不同的传输层协议对Socket的实现不同

  • 套接字(Socket)是计算机网络编程中用于实现进程间通信或网络通信的一种机制。它是一种抽象层,封装了网络传输协议的复杂性,使得应用程序可以简单地通过套接字接口来进行网络通信。

  • 在TCP/IP协议栈中,套接字可以理解为应用程序和网络之间的接口。通过套接字,应用程序可以向网络发送数据,接收数据,并与远程计算机建立连接。

UDP

UDP协议实现 :

两端平等 : 发送端 接口端

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

数据报包(Data Datagram)是在网络中传输的一种数据单元。它通常包含了发送者和接收者的网络地址以及传输的数据。数据报包是在 OSI 模型中的传输层或网络层中使用的,用于实现数据的分组和传输。

DatagramSocket

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

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

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

DatagramPacket : 该类表示数据报包。
//DatagramPacket​(byte[] buf, int length) 构造 DatagramPacket用于接收长度为 length数据包。  
//DatagramPacket​(byte[] buf, int offset, int length) 构造 DatagramPacket用于接收长度为 length数据包,指定缓冲区的偏移量。  
//DatagramPacket​(byte[] buf, int offset, int length, InetAddress address, int port) 构造一个数据报包,用于将长度为 length且偏移量为 ioffset的数据包发送到指定主机上的指定端口号。  
//DatagramPacket​(byte[] buf, int offset, int length, SocketAddress address) 构造一个数据报包,用于将长度为 length且偏移量为 ioffset的数据包发送到指定主机上的指定端口号。  
//DatagramPacket​(byte[] buf, int length, InetAddress address, int port) 构造一个数据报包,用于将长度为 length的数据包发送到指定主机上的指定端口号。  
//DatagramPacket​(byte[] buf, int length, SocketAddress address) 构造数据报包,用于将长度为 length的数据包发送到指定主机上的指定端口号。  

UDP协议下的基本流程

发送端

1.定义我是发送端

2.准备数据

3.打包

4.发送

5.关闭

public class Class001_Send {
    public static void main(String[] args) throws IOException {
        System.out.println("----------------发送端-----------------");
        //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();
    }
}

接收端

1.定义我是接收端

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

3.接收数据

4.处理数据

5.关闭

public class Class002_Receive {
    public static void main(String[] args) throws IOException {
        System.out.println("--------------------接收端------------------");
        //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 :

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

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

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

TCP协议下实现基本流程

客户端

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

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

2.准备数据

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

4.刷出

5.关闭

public class Class001_Client {
    public static void main(String[] args) throws IOException {
        System.out.println("--------------我是客户端--------------");
        //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.关闭

public class Class002_Server {
    public static void main(String[] args) throws IOException {
        System.out.println("--------------我是服务器--------------");
        //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.关闭

public class Class003_LoginClient {
    public static void main(String[] args) throws IOException {
        System.out.println("--------------我是客户端--------------");
        //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.关闭
        os.close();
        bf.close();
        client.close();
    }
}

服务端

TCP协议下实现单向登录流程 : 服务端

1.定义我是服务器

2.阻塞式监听

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

4.处理数据

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

5.关闭

public class Class004_LoginServer {
    public static void main(String[] args) throws IOException {
        System.out.println("--------------我是服务器--------------");
        //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.处理数据
        //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];
            }
        }
        if("admin".equals(uname) && "1234".equals(upwd)){
            System.out.println("登录成功");
        }else{
            System.out.println("用户名或密码错误");
        }
        //5.关闭
        is.close();
        client.close();
        server.close();
    }
}

双向登录
客户端

TCP协议下实现双向登录流程 : 客户端

1.定义我是客户端

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

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

4.刷出

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

6.处理结果

7.关闭

public class Class005_LoginTwoWayClient {
    public static void main(String[] args) throws IOException {
        System.out.println("--------------我是客户端--------------");
        //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();
    }
}

服务端

TCP协议下实现双向登录流程 : 服务端

1.定义我是服务器

2.阻塞式监听

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

4.处理数据

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

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

6.刷出

7.关闭

public class Class006_LoginTwoWayServer {
    public static void main(String[] args) throws IOException {
        System.out.println("--------------我是服务器--------------");
        //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协议下实现多用户登录流程 : 服务端

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

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

public class Class007_LoginMulServer {
    public static void main(String[] args) throws IOException {
        System.out.println("--------------我是服务器--------------");
        //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();
    }
}

多线程

TCP协议下实现多用户登录流程 : 服务端

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


public class Class008_LoginMulServer {
    public static void main(String[] args) throws IOException {
        System.out.println("--------------我是服务器--------------");
        //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、付费专栏及课程。

余额充值