标题图
前言
感谢! 承蒙关照~
探索Java中的网络编程技术
网络编程就是io
技术和网络技术的结合,网络模型的定义,只要共用网络模型就可以两者连接.网络模型参考.
osi模型
TCP/IP参考模型
一座塔有七层,我们需要闯关.
第一层物理层->第二层数据链路层->第三层网络层->第四层传输层->第五层会话层->第六层表示层->第七层应用层.
物理层是主要定义物理设备标准,数据链路层是主要讲从物理层接收的数据进行MAC
地址(网卡的地址)的封装与解封装.这层的数据较帧.
网络层是将从下层接收到的数据进行IP
地址的封装和解封装.传输层是定义一些传输数据的协议和端口号.
会话层是将通过传输层建立数据传输的通路.表示层是进行对接收的数据进行解释,加密与解密.
应用层主要是一些终端的应用.
应用层 --> 传输层 --> 网络层 --> 主机至网络层
效果
效果
电脑通讯要点:
一需要IP
地址:InetAddress
(互联网协议即是规则)
二需要端口号
三需要传输协议
IP
地址,网络中设备的标识,不容易记住,可以用主机名,本地回环地址: 127.0.0.1
主机名就是 localhost
了.所谓局域网就是局部范围内的,互联网就是全球的.
端口号是用来标识进程的逻辑地址,不同进行的标识,有效的端口为0到65535
,其中0到1024
系统使用或保留的端口.
传输协议即是通讯的规则,常见的协议为TCP
, UDP
.
java.net
类 InetAddress
java.lang.Object-> java.net.InetAddress
所有已实现的接口有:
Serializable
直接已知子类:
Inet4Address, Inet6Address
public class InetAddress extends Object implements Serializable
这个类表示互联网协议已地址.
效果
地址类型
Class Inet6Address
java.lang.Objectjava.net.InetAddressjava.net.Inet6Address
public final class Inet6Address extends InetAddress
效果
获取ip
地址:
public class IPDemo { public static void main(String[] args) throws UnknownHostException { //获取本地主机地址对象 InetAddress ip = InetAddress.getLocalHost(); System.out.println(ip.getHostAddress() + ":" + ip.getHostName()); } }
域名解析
C:\WINDOWS\system32\drivers\etc
InetAddress
方法
类型 | 方法 | 说明 |
---|---|---|
boolean | equals(Object obj) | 将此对象与指定对象进行比较 |
byte[] | getAddress() | 返回此InetAddress 对象的原始ip 地址. |
static InetAddress[] | getAllByName(String host) | 给定主机的名称,根据系统上配置的名称服务返回其ip 地址数组. |
static InetAddress | getByAddress(byte[] addr) | 给出原始IP 地址的InetAddress 对象 |
static InetAddress | getByAddress(String host, byte[] addr) | 根据提供的主机名和ip 地址创建InetAddress |
static InetAddress | getByName(String host) | 确定主机名称的ip 地址 |
String | getCanonicalHostName() | 获取此ip 地址的完全限定域名 |
String | getHostAddress() | 返回文本显示中的ip 地址字符串 |
String | getHostName() | 获取此ip 地址的主机名 |
网络编程:
1,网络模型:7层--->4层
端口
用于标识进程的逻辑地址,不同进程的标识
有效端口:0到65535,而0到1024系统使用或保留端口
传输协议
常见协议TCP``UDP
TCP和UDP的区别:
TCP: 面向连接,通过三次握手完成,速度慢,可靠。
UDP: 面向无连接,速度快,不可靠。
UDP
是将数据及其源和目的封装成数据包中,不需要建立连接,每个数据报的大小在限制在64k
内,因无连接,是不可靠的协议,不需要连接,但是速度快.
TCP
是需要进行连接的,形成传输数据的通道,在连接中进行大数据量传输,通过三次握手完成连接,是可靠的协议,效率低即是速度慢一点.
网络编程-Socket
网络通讯的要素:
ip
端口
传输协议
ip是用于标识网络中主机的数字标识,而端口是用于标识应用程序的数字,还有传输协议是用于进行数据传输的规则.
实现UDP的通信,TCP传输:客户端,服务端.
Socket
是网络服务提供的一种机制,是通信两端必备的,都要有Socket
,网络通信其实就是Socket
间的通信,数据在两个Socket
间通过io
传输.
两端发送端和接收端-UDP
UDP发送端
Demo
public class UDPSend{ public static void main(String[] args){ System.out.println("udp发送端"); } }
DatagramSocket
public class DatagramSocket extends Object
此类表示用来发送和接收数据报包的套接字.
数据报套接字是包投递服务的发送或接收点.每个在数据报套接字上发送或接收的包都是单独编址和路由的.从一台机器发送到另一台机器的多个包可能选择不同的路由,也可能按不同的顺序到达.
在DatagramSocket
上总是启动UDP
广播发送.为了接收广播包,将DatagramSocket
绑定到通配符地址.
效果
void receive(DatagramPacket p)从此套接字接收数据报包send(DatagramPacket p)从此套接字发送数据报包
public class UDPSend{ public static void main(String[] args) throws IOException{ System.out.println("udp发送端"); DatagramSocket ds = new DatagramSocket(); String text = "hello"; byte[] buf = text.getBytes(); // 将数据转成字节数组 DatagramPacket dp = new DatagramPacket(buf, buf.length, InetAddress.getByName("123.23232.323.2"),10000); ds.send(dp); ds.close(); } }// 建立upd的socket,具备发送或接收功能// 将数据封装到数据包中,数据包对象是DatagramPacket.// 使用socket对象的send方法将数据包发出去.// 关闭资源
udp
接收端
public class updDemo { public static void main(String[] args) throws IOException { System.out.println("udp 接收端"); // 先有udpsocket服务 // 接收数据 DatagramSocket ds = new DatagramSocket(); 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()); // 关闭资源。 ds.close(); } }
receive
public void receive(DatagramPacket p) throws IOException 此套接字接收数据报包
实现UDP的通信,udp传输涉及的两个对象,即可以发送,又可以接收.TCP传输:客户端,服务端.
UDP
键盘输入
public class UDPSend { public static void main(String[] args) throws IOException { System.out.println("udp 发送端 run");// 1,建立udp的socket它具备者发送或者接收功能。 DatagramSocket ds = new DatagramSocket(9999);// 2,将数据封装到数据包中。数据包对象是DatagramPacket。数据来自于键盘录入。 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("192.168.1.223"), 10001);// 3,使用socket对象的send方法将数据包发送出去。 ds.send(dp); }// 4,关闭资源。 ds.close(); } }
public class UDPRece { public static void main(String[] args) throws IOException { System.out.println("udp2 接收端 run"); DatagramSocket ds = new DatagramSocket(10001); while (true) { // 2,接收数据。 // 3,先定义数据包。 byte[] buf = new byte[1024]; DatagramPacket dp = new DatagramPacket(buf, buf.length); ds.receive(dp); // 4,通过数据包对象获取数据包的内容,发送端的ip。发送端的端口,发送过来的数据。 String ip = dp.getAddress().getHostAddress(); int port = dp.getPort(); String text = new String(dp.getData(), 0, dp.getLength()); System.out.println(ip + ":" + port + ":" + text); } // 5,关闭资源。// ds.close(); } }
案例:
public class UDPChatTest { public static void main(String[] args) throws IOException { //发送端的socket 接收端的socket DatagramSocket sendSocket = new DatagramSocket(); DatagramSocket receSocket = new DatagramSocket(10002); //创建任务对象。 Send send = new Send(sendSocket); Rece rece = new Rece(receSocket); //创建线程并开启。 Thread t1 = new Thread(send); Thread t2 = new Thread(rece); t1.start(); t2.start(); } }// 发送任务class Send implements Runnable { private DatagramSocket ds; public Send(DatagramSocket ds) { super(); this.ds = ds; } @Override public void run() { try { BufferedReader bufr = new BufferedReader(new InputStreamReader( System.in)); String line = null; while ((line = bufr.readLine()) != null) { byte[] buf = line.getBytes();// 将数据转成字节数组。 DatagramPacket dp = new DatagramPacket(buf, buf.length, InetAddress.getByName("1928.1.223"), 10002); ds.send(dp); if ("886".equals(line)) { break; } } // 4,关闭资源。 ds.close(); } catch (IOException e) { } } }// 接收任务。class Rece implements Runnable { private DatagramSocket ds; public Rece(DatagramSocket ds) { super(); this.ds = ds; } @Override public void run() { while (true) { try { 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); if(text.equals("886")){ System.out.println(ip+"....离开聊天室"); } } catch (IOException e) { } } } }
tcp
案例:
public class TCPClient { public static void main(String[] args) throws IOException { System.out.println("客户端运行.......");// 1,建立tcp的客户端socket。明确服务端的地址和端口。 Socket s = new Socket("192.1.223",10003);// 2,如果通道建立成功就会出现socket io流。// 客户端需要做的就获取socket流的中输出流将数据发送目的地服务端。 OutputStream out = s.getOutputStream();// 3,通过socket输出流将数据发送。 out.write("hello tcp 来了!".getBytes());// 4,关闭资源。 s.close(); } }
public class TCPServer { public static void main(String[] args) throws IOException { System.out.println("服务端开启....."); ServerSocket ss = new ServerSocket(10003); while (true) { Socket s = ss.accept(); String ip = 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); s.close(); } } }
案例:
public class TCPClient2 { public static void main(String[] args) throws UnknownHostException, IOException { System.out.println("客户端2 启动......."); Socket s = new Socket("192.1623", 10004); OutputStream out = s.getOutputStream(); out.write("服务端,我来了".getBytes()); 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(); } }
public class TCPSever2 { public static void main(String[] args) throws IOException { System.out.println("服务端2启动....."); ServerSocket ss = new ServerSocket(10004); while (true) { // 获取客户端对象。 Socket s = ss.accept(); // 读取客户端的发送过来的数据 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(); } }
作者:达叔小生
链接:https://www.jianshu.com/p/aee2765b0732