1. 概述
计算机网络:计算机网络是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统。
网络编程的目的:
无线电台…传播交流信息,数据交换。通信想要达到这个效果需要什么:
1.如何准确的定位网络上的一台主机 192.168.16.124:端口, 定位到这个计算机上的某个资源
2.找到了这个主机,如何传输数据呢?
2. 网络通信的要素
(1)如何实现网络的通信?
通信双方地址:
ip
端口号
192.168.16,124:5900
(2)网络编程中的要素:
IP 和 端口号 IP.
网络通信协议 udp,tcp
3.IP
ip地址:InetAddress
唯一定位一台网络上计算机
127.0.0.1 : 本地主机 localhost
ip地址的分类:
ipv4 / ipv6
IPV4 127.0.0.1 , 4个字节组成。, 0~255, 42亿~ ; 30亿都在北美,亚洲4亿。2011年就用尽;
IPV6 :128位。8个无符号整数!
2001:0bb2:aaaa:0015:0000:0000:1aaa:1312!
公网(互联网)- 私网(局域网)
ABCD类地址192.168.xx.xx,专门给组织内部使用的
域名:记忆IP问题!
IP: www.vip.com
public class TestInetAddress {
public static void main(String[] args) {
/**
* IP Address
*/
try {
//查询本机地址
InetAddress byName = InetAddress.getByName("127.0.0.1");
System.out.println(byName);// /127.0.0.1
InetAddress localhost = InetAddress.getByName("localhost");
System.out.println(localhost);// localhost/127.0.0.1
InetAddress host = InetAddress.getLocalHost();// 获得本机IPv4地址 .getLocalHost();
System.out.println(host);// xx/10.0.4.84
//查看网站IP地址
InetAddress inetAddress = InetAddress.getByName("www.baidu.com");
System.out.println(inetAddress);
//常用方法
System.out.println(inetAddress.getCanonicalHostName());//规范名字 获得本机IPv4地址
System.out.println(inetAddress.getHostAddress());//获得本机IPv4地址
System.out.println(inetAddress.getHostName());//域名,或者自己电脑的名字
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
}
4.端口
端口表示计算机上的一个程序的进程;
不同的进程有不同的端口号!用来区分软件!被规定 0~65535
TCP,UDP : 65535 * 2 tcp:80,udp:80吗,单个协议下,端口号不能冲突
端口分类
公有端口 0~1023
HTTP : 80
HTTPS : 443
FTP : 21
Telent : 23
程序注册端口:1024~49151, 分配用户或者程序
Tomcat : 8080
MySQL : 3306
Oracle :1521
动态、私有:49152~ 65535
public class TestInetSocketAddress {
public static void main(String[] args) {
/**
* 端口 port
*/
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());//端口
InetSocketAddress socketAddress2 = new InetSocketAddress("localhost", 8080);
System.out.println(socketAddress2);
}
}
5.通信协议
网络通信协议: 速率,传输码率,代码结构,传输控制……
问题:非常的复杂?
大事化小: 分层!
TCP/IP协议簇:实际上是一组协议
重要:
TCP : 用户传输协议
UDP : 用户数据报协议
出名的协议:TCP:
IP : 网络互连协议
6.TCP与UDP对比
相同点:
UDP协议和TCP协议都是传输层协议。
TCP(Transmission Control Protocol,传输控制协议)提供的是面向连接,可靠的字节流服务。即客户和服务器交换数据前,必须现在双方之间建立一个TCP连接,之后才能传输数据。并且提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端传到另一端。
UDP(User Data Protocol,用户数据报协议)是一个简单的面向数据报的运输层协议。它不提供可靠性,只是把应用程序传给IP层的数据报发送出去,但是不能保证它们能到达目的地。由于UDP在传输数据报前不用再客户和服务器之间建立一个连接,且没有超时重发等机制,所以传输速度很快。
TCP三次握手过程
1.主机A通过向主机B 发送一个含有同步序列号标志位的数据段(SYN)给主机B ,向主机B 请求建立连接,通过这个数据段,主机A告诉主机B 两件事:我想要和你通信;你可以用哪个序列号作为起始数据段来回应我。
2.主机B 收到主机A的请求后,用一个带有确认应答(ACK)和同步序列号(SYN)标志位的数据段响应主机A,也告诉主机A两件事:我已经收到你的请求了,你可以传输数据了;你要用哪个序列号作为起始数据段来回应我。
3.主机A收到这个数据段后,再发送一个确认应答,确认已收到主机B 的数据段:“我已收到回复,我现在要开始传输实际数据了”
TCP四次挥手过程
1.当主机A完成数据传输后,将控制位FIN置1,提出停止TCP连接的请求。
2.主机B收到FIN后对其作出响应,确认这一方向上的TCP连接将关闭,将ACK置1。
3.由B 端再提出反方向的关闭请求,将FIN置1。
4.主机A对主机B的请求进行确认,将ACK置1,双方向的关闭结束。
7.TCP概述
TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF的RFC 793定义。在简化的计算机网络OSI模型中,它完成第四层传输层所指定的功能,用户数据报协议(UDP)是同一层内另一个重要的传输协议。在因特网协议族(Internet protocol suite)中,TCP层是位于IP层之上,应用层之下的中间层。不同主机的应用层之间经常需要可靠的像管道一样的连接,但是IP层不提供这样的流机制,而是提供不可靠的包交换。
传输消息
客户端
连接服务器
Socket发送消息
客户端
public class TcpClientDemo01 {
public static void main(String[] args) {
/**
* 客户端
*/
Socket socket = null;
OutputStream os = null;
try {
//1. 要知道服务器的地址,端口号
InetAddress serverIP = InetAddress.getByName("127.0.0.1");
int port = 9999;
//2. 创建一个socket连接
socket = new Socket(serverIP, port);
//3. 发送消息 IO流
os = socket.getOutputStream();
os.write("你好,欢迎学习狂神说Java" .getBytes());
} catch (Exception e) {
e.printStackTrace();
} finally {
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
服务器
建立服务的端口
ServerSocket等待用户的链接
accept接收用的消息
服务端
public class TcpServerDemo01 {
public static void main(String[] args) {
/**
* 服务端
*/
ServerSocket serverSocket = null;
Socket socket = null;
InputStream is = null;
ByteArrayOutputStream baos = null;
try {
//1. 我得有一个地址
serverSocket = new ServerSocket(9999);
while (true) {
//2. 等待客户端连接过来
socket = serverSocket.accept();
//3. 读取客户端的消息
is = socket.getInputStream();
//管道流
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());
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//关闭资源
if (baos != null) {
try {
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (serverSocket != null) {
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
文件上传
服务器端
public class TcpServerDemo02 {
public static void main(String[] args) throws IOException {
/**
*服务器端
*/
//1. 创建服务
ServerSocket serverSocket = new ServerSocket(9000);
//2. 监听客户端的连接
Socket socket = serverSocket.accept(); //阻塞式监听,会一直等待客户端连接
//3. 获取输入流
InputStream is = socket.getInputStream();
//4. 文件输出
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());
//关闭资源
fos.close();
is.close();
socket.close();
serverSocket.close();
}
}
客户端
public class TcpClientDemo02 {
public static void main(String[] args) throws IOException {
/**
* 客户端
*/
//1.创建一个Socket连接
Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 9000);
//2、 创建一个输出流
OutputStream os = socket.getOutputStream();
//3. 读取文件
FileInputStream fis = new FileInputStream(new File("qinjiang.jpg"));
//4. 写出文件
byte[] buffer = new byte[1024];
int len;
while ((len = fis.read(buffer)) != -1) {
os.write(buffer, 0, len);
}
//通知服务器,我已经结束了
socket.shutdownOutput(); //我已经传输完了!
//确定服务器接收完毕,才能够断开连接
InputStream inputStream = socket.getInputStream();
//String byte[]
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer2 = new byte[2014];
int len2;
while ((len2 = inputStream.read(buffer2)) != -1) {
baos.write(buffer2, 0, len2);
}
System.out.println(baos.toString());
//5.关闭资源
baos.close();
inputStream.close();
fis.close();
os.close();
socket.close();
}
}
8.UDP概述
UDP(User Data Protocol,用户数据报协议)UDP在IP报文的协议号是17。 UDP协议全称是用户数据报协议,在网络中它与TCP协议一样用于处理数据包,是一种无连接的协议。在OSI模型中,在第四层–传输层,处于IP协议的上一层。UDP有不提供数据包分组、组装和不能对数据包进行排序的缺点,也就是说,当报文发送之后,是无法得知其是否安全完整到达的。UDP协议的主要作用是将网络数据流量压缩成数据包的形式。一个典型的数据包就是一个二进制数据的传输单位。每一个数据包的前8个字节用来包含报头信息,剩余字节则用来包含具体的传输数据。
功能
为了在给定的主机上能识别多个目的地址,同时允许多个应用程序在同一台主机上工作并能独立地进行数据包的发送和接收,设计用户数据报协议UDP。使用UDP协议包括:TFTP、SNMP、NFS、DNS、BOOTPUDP使用底层的互联网协议来传送报文,同IP一样提供不可靠的无连接数据包传输服务。它不提供报文到达确认、排序、及流量控制等功能。
发送消息
public class UdpClientDemo01 {
public static void main(String[] args) throws IOException {
//1. 建立一个Socket
DatagramSocket socket = new DatagramSocket();
//2. 建个包
String msg = "你好啊,服务器!";
InetAddress localhost = InetAddress.getByName("localhost");
int port = 9090;
// 数据,数据的长度起始,要发送给谁
DatagramPacket packet = new DatagramPacket(msg.getBytes(), 0, msg.getBytes().length, localhost, port);
//3. 发送包
socket.send(packet);
//4. 关闭流
socket.close();
}
}
接收端
public class UdpServerDemo01 {
public static void main(String[] args) throws IOException {
//开放端口
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();
}
}
9.咨询
public class UdpSenderDemo01 {
public static void main(String[] args) throws IOException {
DatagramSocket socket = new DatagramSocket(8888);
//准备数据: 控制台读取 System.in
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
while (true) {
String data = reader.readLine();
byte[] datas = data.getBytes();
DatagramPacket packet = new DatagramPacket(datas, 0, datas.length, new InetSocketAddress("localhost", 6666));
socket.send(packet);
if (data.equals("bye")) {
break;
}
}
//关闭资源
socket.close();
}
}
public class UdpReceiveDemo01 {
public static void main(String[] args) throws IOException {
DatagramSocket socket = new DatagramSocket(6666);
while (true) {
//准备接收包裹
byte[] container = new byte[1024];
DatagramPacket packet = new DatagramPacket(container, 0, container.length);
socket.receive(packet); //阻塞式接收包裹
//断开连接 bye
byte[] data = packet.getData();
String receiveData = new String(data, 0, data.length);
System.out.println(receiveData);
if (receiveData.equals("bye")) {
break;
}
}
//释放资源
socket.close();
}
}
10.URL概述
统一资源定位符 (Uniform Resource Locator,URL)URL 是对可以从因特网上得到的资源的位置和访问方法的一种简洁的表示。URL 给资源的位置提供一种抽象的识别方法,并用这种方法给资源定位。统一资源定位符只要能够对资源定位,系统就可以对资源进行各种操作,如存取、更新、替换和查找其属性。URL 相当于一个文件名在网络范围的扩展。因此 URL 是与因特网相连的机器上的任何可访问对象的一个指针。
测试代码
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 IOException {
//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(); //断开连接
}
}