• 第78节:Java中的网络编程(上)


    标题图

    第78节:Java中的网络编程(上)

    前言

    网络编程涉及ip,端口,协议,tcp和udp的了解,和对socket通信的网络细节.

    网络编程

    网络模型

    OSI开放系统互连

    网络通讯要素

    网络编程指IO加网络

    OSI模型

    TCP/IP模型

    描述

    TCP/IP模型:

    1. 应用层
    2. 传输层
    3. 网际层
    4. 主机到网络层

    OSI模型:(封装) 网络1封包->网络2拆包

    1. 应用层
    2. 表示层
    3. 会话层
    4. 传输层
    5. 网络层
    6. 数据链路层
    7. 物理层

    网络通讯要素:

    1. ip地址
    2. 端口号
    3. 传输协议

    网络通讯要素

    主机名和ip地址是对应的,默认的主机名:localhost

    java.net
    类 InetAddress
    
    java.lang.Object
    -> java.net.InetAddress
    
    已实现的接口: Serializable
    已知子类: Inet4Address, Inet6Address
    
    public class InetAddress extends Object implements Serializable
    该类表示互联网协议ip地址
    

    ip地址是ip使用32或128位无符号数字,它是一种低级的协议,UDP和TCP协议都是在它的基础上构建的.

    InetAddress的实例包含ip地址,相应的主机名

    升级:

    java.net
    类 Inet6Address
    
    java.lang.Object
    -> java.net.InetAddress
    -> java.net.Inet6Address
    
    所有已实现的接口:Serializable
    
    public final class Inet6Address extends InetAddress
    该类表示互联网协议第6版地址
    

    获取ip地址

    package com.dashucoding.ip;
    
    import java.net.InetAddress;
    import java.net.UnknownHostException;
    
    public class IPDemo {
    
    	public static void main(String[] args) throws UnknownHostException {
    		// TODO Auto-generated method stub
    		// ip地址对象 InetAddress
    
    		// 获取本地主机地址对象
    		InetAddress ip = InetAddress.getLocalHost();
    		// 获取主机地址和主机名
    		System.out.println(ip.getHostAddress() + ":" + ip.getHostName());
    
    		InetAddress ip2 = InetAddress.getByName("192.168.2.151");
    		// 获取主机地址和主机名
    		System.out.println(ip.getHostAddress() + ":" + ip.getHostName());
    
    		// 主机名是需要进行解析的
    	}
    
    }
    

    域名解析_查表

    C:WindowsSystem32driversetc
    

    文件

    Internet协议属性

    DNS域名解析服务器,宽带服务.配置DNS域名服务器主机,一个网址浏览要到它的Ip地址,要找到,就会把ip地址放到DNS域名解析服务器,供给本地使用宽带连接的使用,就可以在浏览器中找到ip地址,浏览网址了.

    DNS服务器软件,把你要浏览的地址ip写进去就可以了

    有些软件需要进行注册序列号?

    // hosts 文件配置
    127.0.0.1 www.###.cn // 该域名地址
    

    端口

    端口,为物理端口,一台电脑发送信息给另一台电脑的软件,发送ip地址完, 要带上端口号, 然后 对应另一台接收消息的软件 有个软件应用程序的数字标识,为逻辑端口, 这样就可以对应发送到另一台电脑上的对应软件接收消息.

    我今天要去一家酒店去了地址,到了楼层, 要知道哪个房间号,才知道对应做什么事.

    端口号

    传输协议

    TCP和UDP: 传输协议,传输规则,通讯规则,传输层.

    TCP和UDP

    UDP,不需要建立连接.我发给你信息,不管你在不在,我就发给你了.我送你东西,写个地址,发到你家就行.有个包,装东西,有大小限制,最多是64k的限制数据.(好处,速度快,不可靠)

    TCP发数据,要确保连接是不是畅通的.TCP是通过三次握手完成的,确保数据的连接畅通.用流行的话语:

    完成了三次TCP握手:

    女朋友发给男朋友
    :"在吗?"

    男朋友回复女朋友
    :"我在!"

    女朋友回复男朋友
    :"我知道了"

    这样爱情可靠,但是很浪费时间的,这样维护情感有点耗时,但是很可靠.

    TCP断开就不传了,UDP不管.电话来形容TCP,对讲机来形容UDP.

    Socket

    Socket

    Socke <-> Socket
    数据在两者之间通过IO传输,传输协议TCP或UDP

    Socket就像两端插口,传输协议不一样,Socket插口也是由不同的类型的.数据在两者之间进行传输,数据是基于网络的io流进行传输的,传输过程就是传入和传出的过程

    UDP_发送端_out

    java.net
    Class DatagramSocket
    java.lang.Object
    -> java.net.DatagramSocket
    
    All Implemented Interfaces: 
    Closeable, AutoCloseable
    已知直接子类:
    MulticastSocket
    
    public class DatagramSocket extends Object implements Closeable
    该类为用于发送和接收数据报数据包的套接字,数据报套接字是分组传送服务的发送或接收点.
    

    例子:

    DatagramSocket s = new DatagramSocket(null); 
    s.bind(new InetSocketAddress(8888));
    
    DatagramSocket s = new DatagramSocket(8888);
    

    构造方法摘要

    方法 说明
    DatagramSocket() 构造数据报套接字并将其绑定到本地主机上的任何可用端口
    DatagramSocket(DatagramSocketImpl impl) 使用指定的DatagramSocketImpl创建一个未绑定的数据报套接字
    DatagramSocket(int port) 构造数据报套接字并将其绑定到本地主机上的指定端口
    DatagramSocket(int port, InetAddress laddr) 创建一个数据报套接字,绑定到指定的本地地址
    DatagramSocket(SocketAddress bindaddr) 创建一个数据报套接字,绑定到指定的本地套接字地址

    receive(DatagramPacket p):从此套接字接收数据报包
    send(DatagramPacket p):从此套接字发送数据报包

    java.net
    Class DatagramPacket
    java.lang.Object
    -> java.net.DatagramPacket
    
    public final class DatagramPacket extends Object
    该类表示数据报包
    
    将数据封装到数据包中,数据包对象为DatagramPacket 
    

    数据包

    DatagramPacket(byte[] buf, int length)
    // 字节数组来的
    

    构造一个DatagramPacket用于接收长度的数据包length.

    receive
    public void receive(DatagramPacket p) throws IOException
    此套接字接收数据报包
    返回, DatagramPacket的缓冲区填充了接收的数据
    数据报包也包含发送的ip地址和发送方的端口号
    

    发送端

    接收端

    UDPSend

    package com.dashucoding.udp;
    
    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    import java.net.SocketException;
    import java.net.UnknownHostException;
    
    public class UDPSend {
    
    	public static void main(String[] args) throws IOException {
    		
    		System.out.println("udp 发送端 run");
    		// 先建立upd的socket 面向对象编程
    		// 将数据封装到数据包中
    		// 使用Socket对象的send方法
    		// 将数据包发送出去
    		// 关闭资源
    		DatagramSocket ds = new DatagramSocket();
    		// 数据
    		String text = "我是发送端,发送的数据";
    		// 将数据转成字节数组
    		byte[] buf = text.getBytes();
    		// 将字节数据封装到数据包中
    		DatagramPacket dp = new DatagramPacket(buf, buf.length, InetAddress.getByName("你的ip地址"),10000);
    		// 发送
    		ds.send(dp);
    		// 发完关掉,不然留着资源干嘛
    		ds.close();
    		
    	}
    
    }
    
    package com.dashucoding.udp;
    
    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.SocketException;
    
    public class UDPRece {
    
    	public static void main(String[] args) throws IOException {
    		System.out.println("udp 接收端 run");
    		// 定义udp接收数据,显示在屏幕上
    		// 先有插座嘛,udpsocket服务
    		// 接收数据前 -> 先将数据存储到数据包中
    		// 先定义数据包
    		// 数据包对象会获取数据包中的内容,发送端的ip和端口
    		// 关闭资源
    		
    		// 有upsocket服务
    		DatagramSocket ds = new DatagramSocket(10000);
    		// 接收数据,接收字节数据
    		byte[] buf = new byte[1024];
    		// 定义包
    		DatagramPacket dp = new DatagramPacket(buf, buf.length);
    		
    		// 还没存到数据包,进行存储
    		ds.receive(dp); // 阻塞
    		
    		String ip = dp.getAddress().getHostAddress();
    		int port = dp.getPort();
    		String text = new String(dp.getData(),0,dp.getLength());
    		
    		System.out.println(ip+" : "+port+" : "+text);
    		// 关闭资源
    		ds.close();
    		
    	}
    
    }
    

    键盘录入

    发送端:

    package com.dashucoding.udp2;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    import java.net.SocketException;
    import java.net.UnknownHostException;
    
    public class UDPSend2 {
    
    	public static void main(String[] args) throws IOException {
    		// TODO Auto-generated method stub
    		System.out.println("udp2 发送端 run");
    		DatagramSocket ds = new DatagramSocket();
    		// 数据来源于键盘录入
    		BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
    		String line = null;
    		while ((line = bufr.readLine()) != null) {
    			if("over".equals(line)) {
    				break;
    			}
    			// 将数据转成字节数组
    			byte[] buf = line.getBytes();
    			// 将字节数据封装到数据包中
    			DatagramPacket dp = new DatagramPacket(buf, buf.length, InetAddress.getByName("你的ip地址"), 10002);
    			ds.send(dp);
    			// 发完关掉,不然留着资源干嘛
    		}
    
    		ds.close();
    	}
    
    }
    

    接收端:

    package com.dashucoding.udp2;
    
    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.SocketException;
    
    public class UDPRece2 {
    
    	public static void main(String[] args) throws IOException {
    		// 有upsocket服务
    		System.out.println("udp2 接收端 run");
    		DatagramSocket ds = new DatagramSocket(10002);
    		while (true) {
    
    			// 接收数据,接收字节数据
    			byte[] buf = new byte[1024];
    			// 定义包
    			DatagramPacket dp = new DatagramPacket(buf, buf.length);
    
    			// 还没存到数据包,进行存储
    			ds.receive(dp); // 阻塞
    
    			String ip = dp.getAddress().getHostAddress();
    			int port = dp.getPort();
    			String text = new String(dp.getData(), 0, dp.getLength());
    
    			System.out.println(ip + " : " + port + " : " + text);
    			// 关闭资源
    		}
    		// ds.close();
    	}
    }
    

    群聊工程

    变化ip地址192.168.1.255
    

    TCP

    Socket()
    通过系统默认类型的SocketImpl创建未连接套接字
    
    Socket(InetAddress address, int port)
    创建一个流套接字并将其连接到指定ip地址的指定端口
    
    Socket(String host, int port)
    创建一个流套接字并将其连接到指定主机上的指定端口号
    
    getOutputStream()
    
    返回此套接字的输出流
    

    网络编程_TCP_服务端

    结构

    package com.dashucoding.tcp;
    
    import java.io.IOException;
    import java.io.OutputStream;
    import java.net.Socket;
    import java.net.UnknownHostException;
    
    public class TCPClient {
    
    	public static void main(String[] args) throws UnknownHostException, IOException {
    		// TODO Auto-generated method stub
    		// 建立tcp的客户端socket 明确服务端的地址和端口
    		// socket io流
    		// 获取socket流
    		
    		System.out.println("客户端运行");
    		// 建立tcp的客户端socket,明确服务端的地址和端口
    		Socket s = new Socket("ip地址",20003);
    		// socket输出流数据发送
    		OutputStream out = s.getOutputStream();
    		// 通过socket输出流将数据发送
    		out.write("hello tcp 来了".getBytes());
    		// 关闭
    		s.close();
    	}
    
    }
    
    package com.dashucoding.tcp;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    public class TCPServer {
    
    	public static void main(String[] args) throws IOException {
    		// TODO Auto-generated method stub
    		// 获取客户端的数据,在屏幕上
    
    		// 思路
    		// 创建服务端的socket,明确端口,监听一个端口
    		// 服务端只要获取到链接过来的客户端就可以和指定的客户端通信了
    		// 通过获取客户端的读取流对象读取客户端发来的数据.
    		// 显示屏幕上
    		System.out.println("服务端运行");
    
    		// 创建服务端的socket,明确接收端口
    		ServerSocket ss = new ServerSocket(20003);
    
    		while (true) {
    			// 服务端只要获取到连接过来的客户端就可以和指定的客户端通信
    			Socket s = ss.accept();
    			String ip = s.getInetAddress().getHostAddress();
    			System.out.println(ip + "...connected");
    
    			// 通过获取客户端的读取流对象读取客户端发送来的数据
    			InputStream in = s.getInputStream();
    			// 流操作
    			byte[] buf = new byte[1024];
    			int len = in.read(buf);
    			String text = new String(buf, 0, len);
    			System.out.println(text);
    			// 关闭
    			s.close();
    		}
    		// ss.close();
    	}
    
    }
    

    客户端和服务端交互

    客户端:

    package com.dashucoding.tcp2;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.Socket;
    import java.net.UnknownHostException;
    
    public class TCPClient2 {
    
    	public static void main(String[] args) throws UnknownHostException, IOException {
    		// TODO Auto-generated method stub
    		// 实现客户端和服务端的收发过程
    		System.out.println("客户端2 启动");
    		// 创建客户端的socket对象 
    		Socket s = new Socket("ip地址",20004);
    		// 发送数据,通过socket输出流完成
    		OutputStream out = s.getOutputStream();
    		out.write("服务端,我来了".getBytes());
    		
    		// 读取服务端返回的数据,通过socket输入流
    		InputStream in = s.getInputStream();
    		byte[] buf=new byte[1024];
    		int len = in.read(buf);
    		String text = new String(buf,0,len);
    		System.out.println(text);
    		
    		// 关闭资源
    		s.close();
    	}
    
    }
    

    服务端:

    package com.dashucoding.tcp2;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    public class TCPServer2 {
    
    	public static void main(String[] args) throws IOException {
    		// TODO Auto-generated method stub
    		System.out.println("服务端2 启动");
    		// 创建tcp服务端socket明确端口
    		ServerSocket ss = new ServerSocket(20004);
    
    		while (true) {
    			// 获取客户端
    			Socket s = ss.accept();
    			System.out.println(s.getInetAddress().getHostAddress() + "...");
    
    			// 读取客户端的发送过来的数据
    			InputStream in = s.getInputStream();
    			byte[] buf = new byte[1024];
    			int len = in.read(buf);
    			String text = new String(buf, 0, len);
    			System.out.println(text);
    			// 给客户端回馈数据
    			OutputStream out = s.getOutputStream();
    			out.write("客户端,我已经收到".getBytes());
    
    			// 关闭客户端
    			s.close();
    		}
    		// 关闭服务端
    		// ss.close();
    	}
    
    }
    

    客户端

    服务端

    小结

    网络编程到网络模型:一开始7层到4层

    传输层的了解

    网络通讯:

    1. ip:用于网络中主机的数字标识
    2. 端口:用于应用程序的数字标识
    3. 传输协议:用于数据传输的规则

    TCP和UDP的区别

    TCP: 面向连接,三次握手,速度慢,可靠
    UDP: 面向无连接,速度快,不可靠

    实现UDP的通信:

    可以发送,又可以接收 DatagramSocket DatagramPacket 数据包对象
    

    实现TCP传输:

    客户端,服务端

    客户端要明确服务端的ip+端口,而服务端要明确端口,通过accept的方法获取客户端对象.

    结言

    那么你是否掌握了,什么是tcp和udp,socket通信机制,以及ip,端口,协议.

    达叔小生:往后余生,唯独有你
    You and me, we are family !
    90后帅气小伙,良好的开发习惯;独立思考的能力;主动并且善于沟通
    简书博客: 达叔小生
    https://www.jianshu.com/u/c785ece603d1

    结语

    • 下面我将继续对 其他知识 深入讲解 ,有兴趣可以继续关注
    • 小礼物走一走 or 点赞
  • 相关阅读:
    Java多线程——volatile关键字、发布和逸出
    线程安全性的基础知识
    maven web不能创建src/main/java等文件等问题
    web环境中的spring MVC
    Spring AOP 概述
    golang统计出其中英文字母、空格、数字和其它字符的个数
    go语言求1到100之内的质数
    golang fmt占位符
    golang---map类型
    golang切片类型
  • 原文地址:https://www.cnblogs.com/dashucoding/p/10331190.html
Copyright © 2020-2023  润新知