网络通讯,UDP.TCP协议
网络通讯
计算机网络
是指将地理位置不一样的具备独立功能的多台计算机及其外部设备,经过通讯线路链接起来,在网络操做系统,网络管理软件及网络通讯协议的管理和协调下,实现资源共享和信息传递的计算机系统。
网络编程
就是用来实现网络互连的不一样计算机上运行的程序间能够进行数据交换。
java
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传编程
网络通讯三要素
IP地址:InetAddress
网络中设备的标识,不易记忆,可用主机名
端口号
用于标识进程的逻辑地址,不一样进程的标识
传输协议
通信的规则
常见协议:TCP,UDP
数组
IP地址
要想让网络中的计算机可以互相通讯,必须为每台计算机指定一个标识号,经过这个标识号来指定要接受数据的计算机和识别发送的计算机,在TCP/IP协议中,这个标识号就是IP地址。服务器
// ip地址对象 // 不能经过构造方法建立 // 根据名字返回第一个全部符合要求的IP地址对象 InetAddress byName = InetAddress.getByName("PC201501241736"); //System.out.println(byName); //这个方法也能够经过ip获取(将ip当作name填入) //若是经过这种方式获取ip对象 那么不能获取计算机名 InetAddress byName2 = InetAddress.getByName("4B5MYUK5PQ2WSNI"); //System.out.println(byName2); //返回指定ip对象表明 的计算机名 System.out.println(byName.getHostName()); //返回指定ip对象表明 的计算机IP地址 System.out.println(byName.getHostAddress());
端口号
物理端口 网卡口
逻辑端口 咱们指的就是逻辑端口
A:每一个网络程序都会至少有一个逻辑端口
B:用于标识进程的逻辑地址,不一样进程的标识
C:有效端口:065535,其中01024系统使用或保留端口。
经过dom命令 netstat -ano能够查看全部占用的端口
网络
通讯协议
UDPdom
将数据源和目的封装成数据包中,不须要创建链接;每一个数据报的大小在限制在64k;因无链接,是不可靠协议;不须要创建链接,速度快socket
数据报协议:将发送的数据分割为指定大小后发送,无需链接接受端,发送端只管发送数据,不管接收端是否接收都会发送tcp
TCP
创建链接,造成传输数据的通道;在链接中进行大数据量传输;经过三次握手完成链接,是可靠协议;必须创建链接,效率会稍低
ide
数据链接协议:数据的发送与接收创建在链接通道的基础上,客户端链接服务端后才能够发送接受请求数据大数据
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
Socket
Socket套接字:
网络上具备惟一标识的IP地址和端口号组合在一块儿才能构成惟一能识别的标识符套接字。
Socket原理机制:
通讯的两端都有Socket。
网络通讯其实就是Socket间的通讯。
数据在两个Socket间经过IO传输。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
使用UDP协议完成数据的发送与接收
发送端思路
1:创建udp的socket服务(建立DatagramSocket对象,发送端无需指定端口)
2:将要发送的数据封装成数据包(建立DatagramPacket对象,传入数据字节数组,数据长度,ip地址对象,接收方接收端口号,将数据格式化)
3:经过udp的socket服务,将数据包发送出(使用DatagramSocket对象的send方法发送数据包)
4:关闭资源(DatagramSocket对象的close方法)
import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.SocketException; import java.net.UnknownHostException; //使用socket 与udp协议实现发送代码的书写 public class UdpSend { public static void main(String[] args) throws IOException { // 1:创建udp的socket服务 DatagramSocket ds = new DatagramSocket(); // 建立使用udp发送数据的socket对象 发送数据使用随机空闲端口 // DatagramSocket ds1 = new DatagramSocket(10000); // 建立使用udp发送数据的socket对象 发送数据使用指定端口 若端口被占用会报错 // 2:将要发送的数据封装成数据包 // (1)准备要发送的数据(数据在网络传输本质字节流) byte[] bytes = "udp发送数据".getBytes(); // (2)建立数据包对象 将数据进行格式化 DatagramPacket dp = new DatagramPacket(bytes, bytes.length, InetAddress.getByName("localhost"), 10000); // 分别传入数据 数据长度 接受地址对象 接受端口号 // 3:经过udp的socket服务,将数据包发送出 ds.send(dp); // 4:关闭资源 ds.close(); } }
接收端思路
1:创建udp的socket服务(建立DatagramSocket对象,接收端须要根据发送端指定端口号) 2:建立接受数据包对象(建立Datagrampacket对象,传入每次接受字节数组以及字节数组长度) 3:经过receive方法接收数据,将收到的数据存储到数据包对象中(调用DatagramSocket对象receive阻塞方法传入Datagrampacket对象) 4:经过数据包对象的功能来完成对接收到数据进行解析.(获取发送方发送时传在数据包中定义的数据信息) 5:能够对资源进行关闭
import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.SocketException; //使用socket udp协议完成数据的接收 public class UdpReceipt { public static void main(String[] args) throws IOException { // 1:创建udp的socket服务 DatagramSocket ds = new DatagramSocket(10000); // 2:经过receive方法接收数据 // (1)建立保存数据的数据包对象 byte[] b = new byte[1024];// 建立接受的字节数组 DatagramPacket dp = new DatagramPacket(b, b.length); //使用字节数组接受数据并存储至数据包中 //(2)使用数据包对象接受数据 ds.receive(dp); //receive是阻塞方法,与scanner的获取数据相似 //当程序执行到这个方法时会暂停运行,当接收到发送端发送的数据后继续执行 // 3:将收到的数据存储到数据包对象中 // 4:经过数据包对象的功能来完成对接收到数据进行解析. InetAddress address = dp.getAddress();//获取请求地址对象 int port = dp.getPort();//获取请求端口 byte[] data = dp.getData();//获取存储数据的字节数组 int length = dp.getLength();//获取数据实际长度 System.out.println(address); System.out.println(port); System.out.println(new String(data, 0, length)); // 5:能够对资源进行关闭 ds.close(); } }
使用UDP完成一对一信息的发送与接收
import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.SocketException; import java.util.Scanner; //使用udp协议完成客户端(既能发送也能接收)书写 public class UdpClient { public static void main(String[] args) { // 建立多个线程分别执行发送与接收 // 接收端线程 new Thread(new Runnable() { @Override public void run() { // 建立udp协议接收端socket对象 try { DatagramSocket ds = new DatagramSocket(10000); // 建立接受数据的数据包对象 byte[] b = new byte[1024]; DatagramPacket dp = new DatagramPacket(b, b.length); // 调用阻塞方法获取请求数据并使用数据包对象接收 while (true) { ds.receive(dp); // 从数据包对象中解析发送的数据 byte[] data = dp.getData();// 数据的字节数组 String hostAddress = dp.getAddress().getHostAddress();// 请求方ip System.out.println(hostAddress + ":" + new String(data, 0, data.length)); } } catch (Exception e) { e.printStackTrace(); } } }).start(); // 发送到线程 new Thread(new Runnable() { @Override public void run() { Scanner sc = new Scanner(System.in); try { // 建立发送端scocket对象 DatagramSocket ds = new DatagramSocket(); while (true) { System.out.println("请输入 接收端ip:发送内容"); String str = sc.nextLine(); String[] split = str.split(":"); // 建立数据包对象并将数据字节数组传入 byte[] b = split[1].getBytes(); DatagramPacket dp = new DatagramPacket(b, b.length, InetAddress.getByName(split[0]), 10000); // 将数据包对象发送至指定接收端 ds.send(dp); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }).start(); } }
使用TCP协议完成数据的发送与接收
接收端(服务器)思路
首先进行接收端的书写,tcp协议创建在链接之上,若是发送端没有链接到服务端则会报错
1:创建服务器端的socket服务(new ServerSocket(端口))
2:服务端没有直接流的操做,而是经过accept方法获取客户端对象,在经过获取到的客户端对象的流和客户端进行通讯(获取链接服务器的客户端socket对象)
3:经过客户端的获取流对象的方法,读取数据或者写入数据(使用getinputStream方法获取输入流读取数据)
4:若是服务完成,须要关闭客户端,而后关闭服务器,可是,通常会关闭客户端,不会关闭服务器,由于服务端是一直提供服务的
import java.io.IOException; import java.io.InputStream; import java.net.ServerSocket; import java.net.Socket; //tcp服务器端(接收端) public class TcpService { public static void main(String[] args) throws Exception { // 1:创建服务器端的socket服务,须要一个端口 ServerSocket ss = new ServerSocket(10000); // 2:服务端没有直接流的操做,而是经过accept方法获取客户端对象,在经过获取到的客户端对象的流和客户端进行通讯 Socket s = ss.accept();// 获取当前链接服务端的客户端对象 // 3:经过客户端的获取流对象的方法,读取数据或者写入数据 String hostAddress = s.getInetAddress().getHostAddress(); System.out.println(hostAddress + "链接服务器"); InputStream is = s.getInputStream(); byte[] b = new byte[1024]; int len = 0; while ((len = is.read(b)) != -1) { System.out.println(new String(b, 0, len)); } // 4:若是服务完成,须要关闭客户端,而后关闭服务器,可是,通常会关闭客户端,不会关闭服务器,由于服务端是一直提供服务的 s.close();// 关闭客户端 ss.close();// 关闭服务器端 } }
发送端(客户端)思路
发送端实际上是将数据封装至发送端socket对象中,而后将socket对象发送至接收端进行接收
1:创建客户端的Socket服务,并明确要链接的服务器。(new)
2:若是链接创建成功,就代表,已经创建了数据传输的通道.就能够在该通道经过IO进行数据的读取和写入.该通道称为Socket流,Socket流中既有读取流,也有写入流.
3:经过Socket对象的方法,能够获取这两个流
4:经过流的对象能够对数据进行传输
5:若是传输数据完毕,关闭资源
import java.io.IOException; import java.io.OutputStream; import java.net.Socket; import java.net.UnknownHostException; //tcp客户端(发送端) public class TcpClient { public static void main(String[] args) throws Exception { // 1:创建客户端的Socket服务,并明确要链接的服务器。 Socket s = new Socket("172.16.1.100", 10000); // 2:若是链接创建成功,就代表,已经创建了数据传输的通道.就能够在该通道经过IO进行数据的读取和写入.该通道称为Socket流,Socket流中既有读取流,也有写入流. // 3:经过Socket对象的方法,能够获取这两个流 OutputStream os = s.getOutputStream(); // 4:经过流的对象能够对数据进行传输 os.write("hello".getBytes()); // 5:若是传输数据完毕,关闭资源 os.flush(); os.close(); s.close(); } }