URI(统一资源标识符)
URI是一个用于标识某一互联网资源名称的字符串,不能用于定位任何资源,唯一作用就是解析。
URL(统一资源定位符)
URL是一种具体的URI,不仅标识了资源,还指明了如何定位到该资源。
互联网上的每个文件都有一个唯一的URL,是访问该文件位置的标准资源地址。
通信三要素,IP,端口,协议。
IP地址决定数据从哪台计算机发送到哪台计算机,端口对应标志哪个应用程序发出,协议规定了传输的数据格式。
InetAddress
public static void demo() throws IOException {
// 获取本机的IP地址对象
InetAddress ipAddress = InetAddress.getLocalHost();
System.out.println("IP地址:" + ipAddress.getHostAddress());
System.out.println("主机名:" + ipAddress.getHostName());
// 获取他人的IP地址
// getByName("") 根据一个主机名或IP地址生成一个IP对象
InetAddress otherIp = InetAddress.getByName("192.168.1.101");
// 返回的是DNS上两个注册服务器
InetAddress[] address3 = InetAddress.getAllByName("www.baidu.com");
System.out.println(address3.length);
}
UDP协议
面向无连接传输,传输速度快,效率高,但是数据包容易丢失,数据包大小限制在64k内。
UDP通讯不分服务端与客户端,只分发送端和接收端。
DatagramSocket(送接收数据包)
DatagramPacket(据包类)
public class Send {
public static void main(String[] args) throws IOException {
sendData();
}
public static void sendData() throws IOException {
// 建立服务
DatagramSocket datagramSocket = new DatagramSocket();
String dataStr = "模拟发送的数据";
// 创建数据包,发送的数据,长度,发送给哪个IP,发送给哪个端口程序
DatagramPacket datagramPacket = new DatagramPacket(dataStr.getBytes(),
dataStr.getBytes().length,
InetAddress.getLocalHost(), 9090);
// 发送资源
datagramSocket.send(datagramPacket);
// 关闭资源,释放占用的端口号
datagramSocket.close();
}
}
public class Receive {
public static void main(String[] args) throws IOException {
receive();
}
public static void receive() throws IOException {
// 建立UDP服务,并监听端口
DatagramSocket datagramSocket = new DatagramSocket(9090);
// 准备空数据包,用于存储数据
byte[] buf = new byte[1024];
DatagramPacket datagramPacket = new DatagramPacket(buf, buf.length);
// 调用UDP服务,接收数据 receive是一个阻塞型的方法,没有接收到数据会一直等待
datagramSocket.receive(datagramPacket);// 数据实际存储到byte[]
// datagramPacket.getLength() 获取数据包存储了多少字节
System.out.println("接收的数据:" +
new String(buf, 0, datagramPacket.getLength()));
datagramSocket.close();
}
}
TCP协议
TCP是基于IO流面向连接进行数据传输的,没有大小限制,通过三次握手的机制保证数据的完整性,是一个可靠协议,相对传输速度慢。
TCP是区分客户端和服务端的
Socket(客户端类)
ServerSocket(服务端类)
如果使用BufferedReader的readLine方法一定要加上 \r\n 把数据写出去。
使用字符流一定要调用flush()数据才会写出。
public class Client {
public static void main(String[] args) throws IOException {
clientDemo();
}
public static void clientDemo() throws IOException {
// 建立服务
Socket socket = new Socket(InetAddress.getLocalHost(), 9090);
// 获得数据输出流,向服务端发送数据
OutputStream outputStream = socket.getOutputStream();
// 写出数据
outputStream.write("模拟客户端数据".getBytes());
// 获得输入流,读取服务端数据
InputStream inputStream = socket.getInputStream();
byte[] buf = new byte[1024];
int data = inputStream.read(buf);
System.out.println("客户端接收的数据:" + new String(buf, 0, data));
// 只关socket数据就可以
socket.close();
}
}
public class Server {
public static void main(String[] args) throws IOException {
serverDemo();
}
public static void serverDemo() throws IOException {
// 建立PC服务端,并且监听端口
// 不需要IP地址,因为是等待别人连接
ServerSocket serverSocket = new ServerSocket(9090);
// accept()接受客户端连接,也是一个阻塞型的方法
Socket socket = serverSocket.accept();
// 获取输入流对象,读取客户端数据
InputStream inputStream = socket.getInputStream();
byte[] buf = new byte[1024];
int len = inputStream.read(buf);
System.out.println("服务端接收数据:" + new String(buf, 0, len));
// //获取输出流,向客户端写数据
OutputStream outputStream = socket.getOutputStream();
outputStream.write("模拟服务端返回数据".getBytes());
serverSocket.close();
}
}