通信协议
- 定义:通过通信信道和设备互连起来的多个不同地理位置的数据通信系统,要使其能协同工作实现信息交换和资源共享,它们之间必须具有共同的语言。交流什么、怎样交流及何时交流,都必须遵循某种互相都能接受的规则
- 协议分类
- TCP/IP:核心:UDP协议和TCP协议
TCP/IP是由一组具有专业用途的多个子协议组合而成的,这些子协议包括TCP、IP、UDP、ARP、ICMP等。TCP/IP凭借其实现成本低、在多平台间通信安全可靠以及可路由性等优势迅速发展,并成为Internet中的标准协议。将TCP/IP作为其默认安装的通信协议- NetBEUI协议
该协议只需进行简单的配置和较少的网络资源消耗,并且可以提供非常好的纠错功能,是一种快速有效的协议。仅适用于基于Windows操作系统的小型局域网中- IPX/SPX协议
主要应用于基于NetWare操作系统的Novell局域网中,基于其他操作系统的局域网 能够通过IPX/SPX协议与Novell网进行通信
- 重要协议:
- UDP协议:用户数据报协议
- TCP协议:用户传输协议
- 出名协议:
- TCP协议:用户传输协议
- IP协议:网络互联协议
传输控制协议(TCP)——连接 稳定 效率低(打电话)
- TCP(传输控制协议)定义了两台计算机之间进行可靠的传输而交换的数据和确认信息的格式,以及计算机为了确保数据的正确到达而采取的措施。
- TCP最大的特点就是提供的是面向连接、可靠的字节流服务
用户数据报协议(UDP)—— 不连接 不稳定 效率高(发短信)
- UDP(用户数据报协议)是一个简单的面向数据报的传输层协议。提供的是非面向连接的、不可靠的数据流传输
- UDP只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地。因此报文可能会丢失、重复以及乱序等
- 但由于UDP在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快
TCP
三次握手 四次挥手
- TCP协议服务端接收数据的步骤:
A:创建接收数据的Socket对象——创建对象的时候要指定端口
B:监听客户端连接——等待客户端连接
C:获取Socket对象的输入流(字节流)
D:读数据,并显示在控制台
E:释放资源
需求:创建一个Socket连接 发送信息
Socket类
- 此类实现客户端套接字 套接字是两台机器间通信的端点
- 定义:Socket是应用层与TCP/IP协议族通信的中间软件抽象层 在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面 对用户来说,一组简单的接口就是全部
作用:
- 连接远程机器
- 发送数据
- 接收数据
- 关闭连接
- 绑定端口
- 监听入站数据
- 在绑定端口上接受来自远程机器的连接
- 一旦建立了连接,本地和远程主机就从这个socket得到输入流和输出流,使用这两个流相互发送数据。连接是全双工的,两台主机都可以同时发送和接收数据 当数据传输结束后,一端或两端将关闭连接
ServerSocket类
- 定义:实现服务器套接字 服务器套接字等待请求通过网络传入。
- 它基于该请求执行某些操作,然后可能向请求者返回结果。
- 构造方法:
ServerSocket(int port) ——创建绑定到特定端口的服务器套接字
- 成员方法:
socket.accept() ——侦听并接受到此套接字的连接
服务端
mport java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class TCPServerDemo {
public static void main(String[] args) {
//服务端
/* A:创建接收数据的Socket对象——创建对象的时候要指定端口
B:监听客户端连接——等待客户端连接
C:获取Socket对象的输入流(字节流)
D:读数据,并显示在控制台
E:释放资源*/
ServerSocket serverSocket = null;
Socket socket = null;
InputStream is = null;
ByteArrayOutputStream baos = null;
try {
// 拥有一个地址
serverSocket = new ServerSocket(9999);————创建绑定到9999端口的套接字
// 等待客户端连接
socket = serverSocket.accept();————接收客户端创建的套接字
// 读取客户端传送过来的信息
is = socket.getInputStream();
// 通过管道流读取信息
// 客户端的输出流 传进管道流的输入流——发送文件
// 管道流的输出流 传进服务端的输入流——读取文件
baos = new ByteArrayOutputStream();
byte[] bytes = new byte[1024 * 8];
int len = 0;
while ((len = is.read(bytes))!=-1){
baos.write(bytes,0,len);// 获取客户端输入的字节
}
System.out.println(baos.toString());
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
serverSocket.close();
socket.close();
baos.close();
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
客户端
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
public class TCPClientDemo {
public static void main(String[] args) {
InetAddress serverIP = null;
Socket socket = null;
OutputStream os = null;
try {
// 获取要连接的服务端的IP地址 和端口号
serverIP = InetAddress.getByName("127.0.0.1");
int port = 9999;
//创建一个Socket连接(套接字)
socket = new Socket(serverIP,port);// 传入服务端的IP和端口号
//发送消息 IO流
os = socket.getOutputStream();
os.write("欢迎来到ZY的学习天地!".getBytes());
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
os.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
文件上传
需求:客户端上传文件到服务端
服务端
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class TCPServerDemo2 {
public static void main(String[] args) throws IOException {
//服务端
// 创建一个端口号
ServerSocket serverSocket = new ServerSocket(9000);
// 监听客户端的连接
Socket socket = serverSocket.accept();// 阻塞式监听:会一直等待客户端连接
// 接收文件——读取文件
InputStream in = socket.getInputStream();
// 创建管道流 先读后写
FileOutputStream fos = new FileOutputStream(new File("Photo.jpg"));
int len = 0;
byte[] bytes = new byte[1024];
while ((len = in.read(bytes))!=-1){
fos.write(bytes,0,len);
}
// 发送消息通知客户端我已经接收完毕
OutputStream os = socket.getOutputStream();
os.write("我接收完毕了 你可以断开了".getBytes());
// 关闭资源
os.close();
fos.close();
in.close();
socket.close();
serverSocket.close();
}
}
客户端
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
public class TCPClientDemo2 {
public static void main(String[] args) throws Exception {
//客户端
//获得服务器的端口号和IP
Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 9000);
//发送文件——写出文件
OutputStream out = socket.getOutputStream();
//创建管道流 先读后写
FileInputStream fis = new FileInputStream(new File("蜡笔小新.jpg"));
int len = 0;
byte[] bytes = new byte[1024];
while ((len = fis.read(bytes))!=-1){
out.write(bytes,0,len);
}
// 通知服务器 我已经传送结束了
socket.shutdownOutput();
// 接收服务端的消息 确认服务端接收完毕
InputStream is = socket.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();// 读取服务端发送的信息
int len2 = 0;
byte[] bytes1 = new byte[1024];
while ((len2 = is.read(bytes1))!=-1){
baos.write(bytes1,0,len2);
}
System.out.println(baos.toString());
// 关闭资源
baos.close();
is.close();
out.close();
fis.close();
socket.close();
}
}
Tomcat服务器
- java后台开发——使用别人写好的Tomcat服务器
- Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选 实际上Tomcat是Apache 服务器的扩展,但运行时它是独立运行的,所以当你运行tomcat 时,它实际上作为一个与Apache 独立的进程单独运行的。
UDP
- 定义:用户数据报协议,属于传输层的协议,无连接,不保证传输的可靠性
- Internet 的传输层有两个主要协议,互为补充
- 无连接的是 UDP——它除了给应用程序发送数据包功能并允许它们在所需的层次上架构自己的协议之外,几乎没有做什么特别的事情
- 面向连接的是 TCP——该协议几乎做了所有的事情
DatagramSocket类
- 此类表示用来发送和接收数据报包的套接字。
- 数据报套接字是包投递服务的发送或接收点
构造方法
DatagramSocket() ——构造数据报套接字并将其绑定到本地主机上任何可用的端口。
DatagramSocket(int port) ——创建数据报套接字并将其绑定到本地主机上的指定端口
成员方法
void receive(DatagramPacket p)——从此套接字接收数据报包
- 接收DatagramPacket的子类包
void send(DatagramPacket p)——从此套接字发送数据报包。
DatagramPacket类
- 此类表示数据报包
构造方法
DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port) ——构造数据报包,用来将长度为 length 偏移量为 offset 的包发送到指定主机上的指定端口号
需求:发送端发消息
发送端
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class UDPSenderDemo {
public static void main(String[] args) throws Exception {
————————发送端——不需要连接服务端
//建立一个DatagramSocket
DatagramSocket datagramSocket = new DatagramSocket();
//建个包
String msg = "你好呀服务器!我来给你发消息了";
InetAddress localhost = InetAddress.getByName("localhost"); // 获取
int port = 9090;
DatagramPacket datagramPacket = new DatagramPacket(msg.getBytes(), 0, msg.getBytes().length, localhost, port);
// 发送包
datagramSocket.send(datagramPacket);
// 关闭资源
datagramSocket.close();
}
}
接收端
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class UDPReceiverDemo {
public static void main(String[] args) throws Exception {
————————接收端
建立一个DatagramSocket 开放端口
DatagramSocket datagramSocket = new DatagramSocket(9090);
//接收数据包
byte[] bytes = new byte[1024];
DatagramPacket datagramPacket = new DatagramPacket(bytes, 0, bytes.length);
//接收数据
datagramSocket.receive(datagramPacket);
//打印数据
System.out.println(datagramPacket.getAddress().getHostAddress());//打印发送端的地址
System.out.println(new String(datagramPacket.getData(),0,datagramPacket.getLength()));
//关闭资源
datagramSocket.close();
}
}
需求:实现循环发送与接收
发送者
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.*;
public class UDPSenderDemo2 {
public static void main(String[] args) throws Exception {
//创建一个Socket
DatagramSocket datagramSocket = new DatagramSocket(8888);
// 控制台读取数据
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
while(true){
String msg = reader.readLine();
byte[] bytes = msg.getBytes();
// 创建一个包
DatagramPacket packet = new DatagramPacket(bytes, 0, bytes.length,InetAddress.getByName("localhost"),6666);
//发送数据
datagramSocket.send(packet);
//断开连接
if(msg.equals("bye")){
break;
}
}
datagramSocket.close();
}
}
接收者
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class UDPReceiverDemo2 {
public static void main(String[] args) throws Exception {
//创建一个Socket
DatagramSocket socket = new DatagramSocket(6666);
//循环接收数据
while (true){
byte[] bytes = new byte[1024];
//创建一个包
DatagramPacket packet = new DatagramPacket(bytes, 0, bytes.length);
// 接收数据
socket.receive(packet);
//读取数据
byte[] data = packet.getData();
String datas = new String(data, 0, data.length);
//打印数据
System.out.println(datas);
//断开连接
if(datas.equals("bye")){
break;
}
}
socket.close();
}
}
URL类
- 定位互联网上的某个资源,eg:网页或者FTP地址
- 定义:代表一个统一资源定位符,它是指向互联网“资源”的指针。资源可以是简单的文件或目录,也可以是对更为复杂的对象的引用,例如对数据库或搜索引擎的查询
- 是一个包含:协议、主机名、端口、路径、查询字符串和参数等的对象
测试代码
public class URLDemo01 {
public static void main(String[] args) throws MalformedURLException {
URL url = new URL("http://localhost:8080/helloworld/index.jsp?username=kuangshen&password=123");
System.out.println(url.getProtocol()); //协议
System.out.println(url.getHost()); //主机ip
System.out.println(url.getPort()); //端口
System.out.println(url.getPath()); //文件
System.out.println(url.getFile()); //全路径
System.out.println(url.getQuery()); //参数
}
}
下载代码
public class UrlDown {
public static void main(String[] args) throws Exception {
//1. 下载地址
URL url = new URL("https://m10.music.126.net/20191201174818/c09b1932384617e535421702c26ccc5c/yyaac/0708/0652/0508/0b9b6827b718aa223af92bd52aa2424f.m4a");
//2. 连接到这个资源 HTTP
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
InputStream inputStream = urlConnection.getInputStream();
FileOutputStream fos = new FileOutputStream("f.m4a");
byte[] buffer = new byte[1024];
int len;
while ((len=inputStream.read(buffer))!=-1){
fos.write(buffer,0,len); //写出这个数据
}
fos.close();
inputStream.close();
urlConnection.disconnect(); //断开连接
}
}