文章目录
概述
网络编程目的:无线电台、传播交流信息、数据交换、通信
想要达到这个效果需要什么:
1. 如何准确地定位网络上的一台主机 192.168.116.124:端口 定位到这个计算机上的某个资源
2. 找到了这个主机,如何传输数据呢??
JavaWeb:网页编程 B/S
网络编程:TCP/IP C/S
网络通信的要素
如何实现网络的通信??
通信双方的地址:
- IP
- 端口号
- 192.168.16.124:8848
规则:网络通信的协议
TCP/IP参考模型
IP
ip地址:InetAddress
- 唯一定位一台网络上计算机
- 127.0.0.1:本机localhost
- ip地址分类
- ipv4 / ipv6
- ==IPV4== 127.0.0.1 4个字节组成
- ==IPV6== 128位。 8个无符号整数!!!
- 公网(互联网)- 私网(局域网)
- ABCD类地址
- 192.168.xx.xx,专门给组织内部使用的
- 域名:记忆IP问题!!!
参考代码
import java.net.InetAddress;
import java.net.UnknownHostException;
//测试IP
public class TestInetAddress {
public static void main(String[] args) {
InetAddress inetAddress1 = null;
InetAddress inetAddress2 = null;
try {
//查询本地主机地址
inetAddress1 = InetAddress.getByName("127.0.0.1");
//查询网络IP地址
inetAddress2 = InetAddress.getByName("www.baidu.com");
} catch (UnknownHostException e) {
e.printStackTrace();
}
System.out.println(inetAddress1);
System.out.println(inetAddress2);
}
}
import java.net.InetSocketAddress;
public class TestInetSocketAddress {
public static void main(String[] args) {
InetSocketAddress inetSocketAddress = new InetSocketAddress("127.0.0.1", 8080);
InetSocketAddress inetSocketAddress1 = new InetSocketAddress("localhost", 8080);
System.out.println(inetSocketAddress);
System.out.println(inetSocketAddress1);
System.out.println(inetSocketAddress.getAddress());
System.out.println(inetSocketAddress.getHostName());
System.out.println(inetSocketAddress.getPort());
}
}
端口
端口表示计算机上的一个程序的进程;
- 不同的进程有不同的端口号!用来区分软件!!!
- 被规定为0 ~ 65535
- 单个协议下,端口号不能冲突
- 端口分类:
- 公有端口0 ~ 1023
- HTTP:80
- HTTPS:443
- FTP:21
- Telent:23
- 程序注册端口:1024 ~ 49151,分配用户或者程序
- Tomcat:8080
- MySQL:3306
- Oracle:1521
- 动态、私有49152 ~ 65535
netstat -ano #查看所有端口
netstat -ano|findstr "5900" #查看指定端口
tasklist|findstr "8696" #查看指定端口的进程
Ctrl + shift + ESC #任务管理器快捷键
通信协议
协议:约定,就好比我们用普通话沟通。
TCP/IP协议层
TCP:用户传输协议
UDP:用户数据报协议
IP:网络互连协议
TCP和UDP对比
TCP:打电话
- 连接,稳定
- 三次握手,四次挥手
#朋友聚会,约伴同行 #最少需要三次,保证稳定连接! A:你要参加聚会嘛??? B:我去!!! A:等会路口见!!! #朋友散会,彼此报平安 #至少需要四次,保证双方关闭 A:我到家了! B:我知道啦! B:我也到家了! A:👌
- 客户端、服务端
- 传输完成,释放连接,效率低
UDP:发短信
- 不连接,不稳定
- 客户端、服务端:没有明确的界限
- 不管有没有准备好,都可以发给你~
- DDOS:洪水攻击!!!(饱和攻击)
TCP
消息传递
客户端
1. 连接服务器Socket
2. 发送消息
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
//客户端
public class TcpClientDemo01 {
public static void main(String[] args) {
try (Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 9999); OutputStream os = socket.getOutputStream()) {
//1.要知道服务器的地址
//2.创建一个socket连接
//3.发送消息 IO流
os.write("你好,欢迎学习网络编程".getBytes(StandardCharsets.UTF_8));
} catch (IOException e) {
e.printStackTrace();
}
}
}
服务器
1. 建立服务器的端口ServerSocket
2. 等待用户的连接accept
3. 接收用的消息
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
//服务端
public class TcpServerDemo01 {
public static void main(String[] args) {
try (ServerSocket serverSocket = new ServerSocket(9_999); Socket socket = serverSocket.accept(); InputStream is = socket.getInputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
//1.我得有一个地址
//2.等待客户端连接过来
//3.读取客户端的消息
//管道流
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();
}
}
}
文件上传
客户端
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
public class TcpClientDemo02 {
public static void main(String[] args) {
try (Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 9000); OutputStream os = socket.getOutputStream(); FileInputStream fis = new FileInputStream("D:\\Soledad-X\\Study\\Java\\JavaSE\\Java基础语法\\src\\com\\net\\lesson02\\Soledad-X.jpg")) {
//1.创建一个Socket连接
//2.创建一个输出流
//3.读取文件
//4.写出文件
byte[] buffer = new byte[1024];
int len;
while ((len = fis.read(buffer)) != -1) {
os.write(buffer, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
服务端
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class TcpServerDemo02 {
public static void main(String[] args) {
try(ServerSocket serverSocket = new ServerSocket(9000); Socket socket = serverSocket.accept(); InputStream is = socket.getInputStream(); FileOutputStream fos = new FileOutputStream("D:\\Soledad-X\\Study\\Java\\JavaSE\\Java基础语法\\src\\com\\net\\lesson02\\receive.jpg")){
//1.创建服务
//2.监听客户端的连接
//3.获取输入流
//4.文件输出
//管道流
byte[] buffer = new byte[1024];
int len;
while ((len = is.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Tomcat
服务端
- 自定义Server
- Tomcat服务器:Java后台开发!
客户端
- 自定义Client
- 浏览器Browser
UDP
发短信:不用连接,需要知道对方的地址!
发送消息
发送端
import java.io.IOException;
import java.net.*;
import java.nio.charset.StandardCharsets;
//不需要连接服务器
public class UdpClientDemo01 {
public static void main(String[] args) {
try {
//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(StandardCharsets.UTF_8).length, localhost, port);
//3.发送包
socket.send(packet);
//4.关闭流
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
接收端
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
//还是需要等待客户端的连接!
public class UdpServerDemo01 {
public static void main(String[] args) {
try {
//1.开放端口
DatagramSocket socket = new DatagramSocket(9090);
//2.接收数据包
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()));
//3.关闭连接
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
聊天实现
功能描述
- 学生和老师各自开启两个线程(发送消息线程和接收消息线程)
- 发送消息线程
- 准备消息:控制台读取System.in
- 准备包裹:packet包裹消息,附带自身IP和端口信息
- 发送包裹
- 接收消息线程
- 准备接收包裹:socket.receive(packet);//阻塞式接受包裹
- 解析包裹:获取包裹中消息
- 显示消息:控制台输出消息
参考代码
URL
统一资源定位符:定位资源的,定位互联网上的某一个资源
DNS域名解析