网络编程
1.1 概述
计算机网络:
计算机网络是指将地理位置不同的计算机及其外部部件,通过通信线路连接起来,在网络编程协议下,实现不同计算机之间的信息共享以及信息交流的计算机系统。
网络编程的目的:
传播交流信息(无线电台):数据交换,通信。
想要达到这些效果需要做什么:
- 如何准确地定位网络上的一台主机 192.168.16.124:端口,定位到这个计算机上的某个资源
- 找到了这个主机,如何传输数据呢?
javaweb:网页编程 B/S
网络编程:TCP/IP C/S
1.2 网络通信的要素
TCP/IP参考模型:
网络编程针对传输层 TCP,UDP
小结:
- 网络编程两个主要问题
- 如何准确定位到网络上的一台或多台主机
- 找到主机之后如何进行通信
- 网络编程中的要素
- 万物皆对象
1.3 IP地址
ip地址:InterAddress
1
| 2001:0bb2:aaaa:0015:0000:0000:1aaa:1312
|
-
- ABCD类地址
- 192.168.xx.xx,专门给组织内部使用
练习:InetAddress类的常用方法
1 2 3 4 5 6 7 8 9
| InetAddress address = InetAddress.getByName("www.baidu.com"); System.out.println(address);
System.out.println(address.getHostAddress()); System.out.println(address.getAddress()); System.out.println(address.getCanonicalHostName()); System.out.println(address.getHostName());
|
1.4 端口
端口表示计算机上的一个程序的进程;
- 不同的进程有不同的端口号!用来区分软件!
- 被规定0 ~ 65535(电脑最多跑的进程数)
- TCP,UDP:65535 * 2 ,单个协议下,端口号不能冲突(tcp:80 udp:80可以)
分类:
1 2 3 4
| netstat -ano #查看所有的端口 netstat -ano | finstr "5900" #查看指定的端口 tasklist | findstr "8696" #查看指定端口的进程 ctrl + shift + ESC #打开任务管理器,死机也能用
|
练习:InetSocketAddress类
1 2 3 4 5 6 7 8 9 10 11
| public class TestInetSocketAddress { public static void main(String[] args) { InetSocketAddress socketAddress = new InetSocketAddress("127.0.0.1",8080); System.out.println(socketAddress);
System.out.println(socketAddress.getAddress()); System.out.println(socketAddress.getHostName()); System.out.println(socketAddress.getPort()); } }
|
协议:约定,就好比我们现在说的是普通话。
网络通信协议:速率,传输码率,传输控制……
问题:非常的复杂?
大事化小:分层!
TCP/IP协议簇:
重要的两个协议:
TCP:用户传输协议
UDP:用户数据报协议
出名的协议:TCP,IP(网络互连协议),实际上是一组协议
TCP,UDP对比:
TCP:打电话
- 连接:稳定
- 三次握手 四次挥手
- 客户端,服务端
- 传输完成,释放连接、效率低
UDP:发短信
- 连接:不稳定
- 客户端,服务端没有明显的界限
- 不管有没有准备好,都可以发给你(导弹)
- DDOS:洪水攻击!饱和攻击
扩展:三次握手,四次挥手
1 2 3 4 5 6 7 8 9 10
| 最少需要三次,保证稳定连接! A:你瞅啥? #第一次握手:客户端向服务端申请连接 B:瞅你咋地?#第二次握手:服务端向客户端返回确认同意连接 A:干一场! #第三次握手:客户端发送确认报文段,完成连接
A:我要走了 B:你真的要走了吗? B:你真的真的要走了吗? A:我真的要走了
|
1.6 TCP协议
客户端:
- 连接服务器 Socket(address,port)
- 发送消息
1 2 3 4 5 6 7 8 9 10 11 12
| InetAddress address = InetAddress.getByName("127.0.0.1"); int port = 9999;
Socket socket = new Socket(address, port);
OutputStream os = socket.getOutputStream(); os.write("Hello World".getBytes());
socket.close(); os.close();
|
服务器:
- 建立服务的端口 ServerSocket
- 等待用户的连接 accept()
- 接收用户的消息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| ServerSocket serverSocket = new ServerSocket(9999);
Socket socket = serverSocket.accept();
InputStream is = socket.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len; while((len = is.read(buffer))!=-1){ baos.write(buffer,0,len); } System.out.println(baos.toString());
baos.close(); is.close(); socket.close(); serverSocket.close();
|
TCP文件上传
服务器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| package com.mine.lesson2;
import java.io.*; import java.net.ServerSocket; import java.net.Socket;
public class TcpServerDemo02 { public static void main(String[] args) throws IOException { ServerSocket serverSocket = new ServerSocket(9000); Socket socket = serverSocket.accept(); InputStream is = socket.getInputStream();
FileOutputStream fos = new FileOutputStream(new File("receive.jpg")); byte[] buffer = new byte[1024]; int len; while((len=is.read(buffer))!=-1){ fos.write(buffer,0,len); }
OutputStream os = socket.getOutputStream(); os.write("接收完毕,可以断开连接了".getBytes());
os.close(); fos.close(); is.close(); socket.close(); serverSocket.close(); } }
|
客户端:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| package com.mine.lesson2;
import java.io.*; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException;
public class TcpClientDemo02 { public static void main(String[] args) throws Exception { Socket socket = new Socket(InetAddress.getByName("127.0.0.1"),9000); OutputStream os = socket.getOutputStream(); FileInputStream fis = new FileInputStream(new File("刀妹06.jpg")); byte[] buffer = new byte[1024]; int len; while((len=fis.read(buffer))!=-1){ os.write(buffer,0,len); }
socket.shutdownOutput();
InputStream is = socket.getInputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buffer2 = new byte[1024]; int len2; while ((len2=is.read(buffer2))!=-1){ baos.write(buffer2,0,len2); } System.out.println(baos.toString());
baos.close(); is.close(); fis.close(); os.close(); socket.close(); } }
|
初识Tomcat
服务端:
- 自定义 C
- Tomcat服务器 S:Java后端开发
客户端:
1.7 UDP
数据报包(DatagramSocket)发送与接收
发送端:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| package com.mine.lesson3;
import java.net.*;
public class UdpClientDemo01 { public static void main(String[] args) throws Exception { DatagramSocket socket = new DatagramSocket();
String msg="你好,服务器!"; InetAddress address = InetAddress.getByName("localhost"); int port=9090; DatagramPacket packet = new DatagramPacket(msg.getBytes(), 0, msg.getBytes().length, address, port);
socket.send(packet);
socket.close(); } }
|
接收端:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| package com.mine.lesson3;
import java.net.DatagramPacket; import java.net.DatagramSocket;
public class UdpServerDemo01 { public static void main(String[] args) throws Exception { DatagramSocket socket = new DatagramSocket(9090);
byte[] buffer = new byte[1024]; DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);
socket.receive(packet);
System.out.println(packet.getAddress().getHostAddress()); System.out.println(new String(packet.getData(),0,packet.getLength())); socket.close(); } }
|
UDP聊天实现
循环发送消息
发送方:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| DatagramSocket socket = new DatagramSocket();
while (true) {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); String data = reader.readLine(); byte[] datas = data.getBytes(); DatagramPacket packet = new DatagramPacket(datas, 0, datas.length, new InetSocketAddress("127.0.0.1", 6666));
socket.send(packet);
if(data.equals("bye")) break; }
socket.close();
|
接收者:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| 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 receiveData = new String(data, 0, data.length); System.out.println(receiveData);
if (receiveData.equals("bye")) { break; } }
socket.close();
|
多线程在线咨询
1.8 URL
https://www.baidu.com
统一资源定位符:定位资源的,定位互联网上的某一个资源
DNS域名解析 www.baidu.com xxx.x.xx.xx
协议://ip地址:端口/项目名/资源
1 2 3 4 5 6 7
| URL url = new URL("http://localhost:8080/helloworld/index.jsp?username=root"); System.out.println(url.getProtocol()); System.out.println(url.getHost()); System.out.println(url.getPort()); System.out.println(url.getPath()); System.out.println(url.getFile()); System.out.println(url.getQuery());
|
下载文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public class URLDown { public static void main(String[] args) throws IOException { URL url = new URL("https://m701.music.126.net/20210505164644/b272db6641b6e975c78e51e182d1211d/jdyyaac/obj/w5rDlsOJwrLDjj7CmsOj/8698723658/63d4/2446/ae0d/788e204c24f3497eb896a9112fa6baac.m4a");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
InputStream inputStream = urlConnection.getInputStream();
FileOutputStream fos = new FileOutputStream("mine.m4a"); byte[] bytes = new byte[1024]; int len; while ((len=inputStream.read(bytes))!=-1){ fos.write(bytes,0,len); }
fos.close(); inputStream.close(); urlConnection.disconnect(); } }
|