基础知识
网络的三要素:
-
1)
IP
地址- 每个设备在网络中的唯一标识。
- 每台网络终端终端在网络中都有一个独立的地址,我们在网络中传输数据就是使用这个地址。
-
2)端口号
- 既然
IP
地址可以找到一个唯一的设备,那么端口号就是每个程序在设备上的唯一标识。 - 每个网络程序都需要绑定一个端口号,传输数据的时候除了确定发到哪台机器上,还要明确发到哪个程序。
- 端口号范围是0 ~ 65536,其中0 ~ 1023是系统程序占用的,例如:
端口号 名称 注释 21 ftp 文件传输协议端口 22 ssh 安全 Shell 服务 80 http 用于万维网(WWW)服务的超文本传输协议 443 https 安全超文本传输协议 - 既然
-
3)网络协议
- 为计算机网络中进行数据交换而建立的规则、标准或约定的集合。
UDP
- 面向无连接,数据不安全,速度相比
TCP
快。 - 不区分客户端与服务端,只区分发送端和接收端。
- 面向无连接,数据不安全,速度相比
TCP
- 面向连接(三次握手),数据安全,速度略低。分为客户端和服务端。
- 三次握手: 客户端先向服务端发起请求, 服务端响应请求, 传输数据。
Socket 的定义
- 即套接字,是应用层 与
TCP/IP
协议族通信的中间软件抽象层,表现为一个封装了 TCP / IP协议族 的编程接口(API)。
- Socket不是一种协议,而是一个编程调用接口(API),属于传输层(主要解决数据如何在网络中传输)。
- 即:通过Socke,我们才能在Java、Andorid平台上通过 TCP/IP协议进行开发。
- 对用户来说,只需调用Socket去组织数据,以符合指定的协议,即可通信。
- 一个
Socket
实例,唯一代表一个主机上的一个应用程序的通信链路。 - 网络上具有唯一标识的IP地址和端口号组合在一起才能构成唯一能识别的标识符套接字。
- 通信的两端都有
Socket
。 - 网络通信其实就是
Socket
间的通信。 - 数据在两个
Socket
间通过IO
流传输。 - Socket在应用程序中创建,通过一种绑定机制与驱动程序建立关系,告诉自己所对应的
IP
和port
。
UDP
UDP(User Datagram Protocol),也就是用户数据包协议。关键点在于“数据包”。主要就是把数据进行打包然后丢给目标,而不管目标是否接收到数据。
使用UDP传输的类是DatagramSocket
,构造方法如下:
- 空参构造方法表示随机分配一个端口号。
- 参数中的
SocketAddress
是一个抽象类,其实现类InetSocketAddress
==InetAddress
+port
- 创建数据报套接字并将其绑定到本地主机上的
IP
和指定端口
**使用DatagramPacket
来包装数据,构造方法如下: **
- 第1个一般用来装接收的数据,用来接收长度为
length
的数据包。 - 第2个用来用来将长度为
length
的包发送到指定主机上的指定端口号,length
参数必须小于等于buf.length
。
使用步骤
-
- 发送Send
- 创建DatagramSocket, 指定发送端的端口号(空参表示随机,无法大量并发)
- 创建DatagramPacket, 指定数据, 长度, 地址, 端口
- 使用DatagramSocket发送DatagramPacket
- 关闭DatagramSocket
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;
public class Test_Send {
public static void main(String[] args) throws IOException {
DatagramSocket socket = new DatagramSocket(); // 创建UDP Socket,此空参数构造使得发送端口号为随机端口,最好指定固定的
Scanner scanner = new Scanner(System.in);
while (true) {
String line = scanner.nextLine();
DatagramPacket packet = new DatagramPacket( // 数据包
line.getBytes(), // 发送数据的字节数组
line.length(), // 发送
InetAddress.getLocalHost(), // 向本地IP发送,因为两个程序在一起
1314); // 指定目标端口
socket.send(packet); // 发送
if ("quit".equals(line)) { // 发送quit后则结束
break;
}
}
scanner.close();
socket.close();
}
}
-
- 接收Receive
- 创建DatagramSocket, 指定端口号
- 创建DatagramPacket, 指定数组, 长度
- 使用DatagramSocket接收DatagramPacket
- 关闭DatagramSocket
- 从DatagramPacket中获取数据
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class Test_Receive {
public static void main(String[] args) throws IOException {
DatagramSocket socket = new DatagramSocket(1314);
while (true) {
DatagramPacket packet = new DatagramPacket(new byte[1024], 1024);
socket.receive(packet);
byte[] data = packet.getData();
int len = packet.getLength();
String str = new String(data,0,len);
if ("quit".equals(str)) { // 接收到quit后则结束
break;
}
System.out.println(str);
}
socket.close();
}
}
-
- 运行结果:
- 发送端:
- 接收端:
- 接收方获取ip和端口号的方法
- String ip = packet.getAddress().getHostAddress();
- int port = packet.getPort();
下一篇是TCP
。