1. 网络通信的要素
ip:端口
- 网络通信协议
2. 网络通信的两种模型
2.1. C/S
一套程序为客户端,另外一套程序为服务器端
这种开发可以由开发者自定义传输协议,并且使用一些比较私密的端口
所以安全性是比较高的,但是开发与维护成本比较高
其分为两种开发:TCP(可靠的数据连接)、UDP(不可靠的数据连接)
2.2. B/S
只开发一套服务器端的程序,使用的是公共的HTTP协议并且使用的公共的 80 端口,所以其安全性相对较差
3. TCP通信
使用两个类实现数据的交互处理:ServerSocket (服务器端)、Socket(客户端)
3.1. ServerSocket
public class Server {
public static void main(String[] args) throws Exception {
// 实例化一个 ServerSocket 对象
ServerSocket server = new ServerSocket(888);
System.out.println("listening......");
// 监听端口,等待客户端连接
Socket client = server.accept();
// 接收客户端的输入流
Scanner scan = new Scanner(client.getInputStream());
// 向客户端发送数据
PrintStream out = new PrintStream(client.getOutputStream());
boolean flag = true;
while (flag){
// 如果接收到客户端的信息
if (scan.hasNext()){
String val = scan.next();
if ("stop".equals(val)){
out.println("stop server!!!");
flag = false;
}else {
// 向客户端返回数据
out.println("【echo】" + val);
}
}
}
server.close();
scan.close();
out.close();
client.close();
}
}
3.2. Socket
public class Socket {
// 接收键盘的输入内容
public static Scanner keyboard = new Scanner(System.in);
public static void main(String[] args) throws Exception {
// 连接服务器
Socket client = new Socket("localhost", 888);
// 接收服务器端的输入流
Scanner scan = new Scanner(client.getInputStream());
// 向服务器端发送内容
PrintStream out = new PrintStream(client.getOutputStream());
boolean flag = true;
while (flag){
String input = getString("【input content】");
out.println(input);
// 如果服务器端有响应
if (scan.hasNext()){
System.out.println(scan.next());
}
// 如果输入 stop 就停止
if ("stop".equals(input)){
flag = false;
}
}
client.close();
out.close();
scan.close();
keyboard.close();
}
// 接收键盘的输入
public static String getString(String prompt) throws Exception{
System.out.println(prompt);
String str = keyboard.next();
return str;
}
}
连接建立后,通过 I/O 流进行通信,每一个socket都有一个输出流和一个输入流,客户端的输出流连接到服务器端的输入流,而客户端的输入流连接到服务器端的输出流。
TCP 是一个双向的通信协议,因此数据可以通过两个数据流在同一时间发送。
4. UDP通信
实现UDP程序需要两个类:DatagramPacket(数据内容)、DatagramSocket (网络发送与接收) 数据报的发送:客户端是否接收到与发送者无关
4.1. 客户端
public class UDPClient {
public static void main(String[] args) throws Exception {
// 客户端接收信息的端口
DatagramSocket client = new DatagramSocket(888);
byte[] data = new byte[1024];
DatagramPacket packet = new DatagramPacket(data,data.length);
System.out.println("waiting accept content...");
// 接收消息
client.receive(packet);
System.out.println("【accepted content】" + new String(data,0,packet.getLength()));
client.close();
}
}
4.2. 服务端
public class UDPServer {
public static void main(String[] args) throws Exception {
// 服务端发送信息的端口
DatagramSocket server = new DatagramSocket(88);
String str = "www.baidu.com";
// 发送数据
DatagramPacket packet = new DatagramPacket(str.getBytes(),0,str.length(), InetAddress.getByName("localhost"),888);
server.send(packet);
System.out.println("message sended");
server.close();
}
}
5. URL下载网络资源
public class demo {
public static void main(String[] args) throws Exception {
// 资源地址
URL url = new URL("https://img1.wallspic.com/previews/8/8/9/1/7/171988/171988-genshin_impact_ling_xiang_nu_pu-hoyolab-ka_tong-bai_se-zi_se_de-x750.jpg");
// 连接资源
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
// 请求资源
InputStream inputStream = urlConnection.getInputStream();
// 设置文件
FileOutputStream fos = new FileOutputStream("test.jpg");
// 临时缓存
byte[] buffer = new byte[1024];
int len;
while ((len=inputStream.read(buffer)) != -1){
// 将请求得到的数据写入文件
fos.write(buffer,0,len);
}
// 关闭IO
fos.close();
inputStream.close();
urlConnection.disconnect();
}
}