网络编程基础01
网络编程
概述
信件
计算机网络
计算机网络是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路和通信设备连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统
网络编程的目的 --> 传播交流信息,数据的交换,通信
早先年的无线电台 --> 传播交路信息
想要达到这个效果需要什么
- 如何准确的定位网络上的一台主机? 127.0.0.1 --> 端口号 定位到这个计算机上的某个资源
- 找到了这个主机,如何传输数据呢?
javaweb --> 网页编程 B/S
网络编程 --> TCP/IP C/S
网络通信的要素
如何实现网络通信?
-
通信双方的地址
-
IP
-
端口号: 127.0.0.1
-
-
规则 --> 网络通信协议
- TCP/IP参考模型
重点学习
小结
- 网络编程中有两个主要的问题
- 如何准确的定位到网络上的一台或者多台主机
- 找到主机之后如何进行通信
-
网络编程中的要素
- IP 和 端口号
- 网络编程协议 --> udp, tcp
-
万物皆对象
IP
ip地址 --> 在InetAddress类包中
-
唯一定位一台网络上的计算机
-
本机 --> 127.0.0.1 localhost
-
ip地址的分类
-
Ip地址分类 --> ipv4/ipv6
- IPV4 --> 127.0.0.1 由4个字节组成 0~255 42亿 30亿在北美,4亿在亚洲,2011年就用尽了
- IPV6 --> 128位. 8个无符号整数 fe80::8ffa:7f1a:9f4b:b70a%16 --> 不全
// IPV6格式 2001:0bb2:aaaa:0012:0000:0000:1aaa:1312!
-
公网(是给互联网使用的) - -私网(局域网)
- A B C D类地址
- 192.168.xxx.xx --> 局域网 专门给组织内部使用
-
-
域名 --> 记忆IP问题!
- IP --> www.vip.com
//测试IP
public class TextInetAddress {
public static void main(String[] args) {
try {
//查询本机地址
InetAddress inetAddress01 = InetAddress.getByName("127.0.0.1");
System.out.println(inetAddress01);
InetAddress inetAddress03 = InetAddress.getByName("localhost");
System.out.println(inetAddress03);
InetAddress inetAddress04 = InetAddress.getLocalHost();
System.out.println(inetAddress04);
//查询网站ip地址 返回过程会变慢
InetAddress inetAddress02 = InetAddress.getByName("www.baidu.com");
System.out.println(inetAddress02);
//常用方法
System.out.println("===========隔断============");
System.out.println(inetAddress02.getAddress()); // 返回一组地址
System.out.println(inetAddress02.getCanonicalHostName()); // 规范的名字
System.out.println(inetAddress02.getHostAddress()); // ip
System.out.println(inetAddress02.getHostName()); //域名 或者自己电脑的名字
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
}
端口
端口表示计算机上的一个程序的进程
-
不同的进程有不同的端口号, 端口号不能冲突. 用来区分软件
-
端口号范围被规定 0~65535
-
端口分为TCP端口和UDP端口, 每一个协议下面都有65535个端口号. 单个协议下, 端口号不能冲突
-
端口分类
-
公有端口 0~1023
- HTTP: 默认80端口
- HTTPS: 443
- FTP: 21
- Telent: 23
-
程序注册端口: 1024~49151, 分配给用户或者程序
- Tomcat: 8080
- MySQL: 3306
- Oracle: 1521
-
动态, 私有端口: 49152~65535
- idea默认端口号63342
# cmd查看所有的端口 netstat -ano # 查找指定的端口 netstat -ano|finder "5900" # 查看指定端口的进程 tasklist|finder "8696"
实现信息传递
public class TestInetSocketAddress { public static void main(String[] args) { InetSocketAddress socketAddress = new InetSocketAddress("127.0.0.1", 8080); InetSocketAddress socketAddress2 = new InetSocketAddress("localhost", 8080); System.out.println(socketAddress); System.out.println(socketAddress2); System.out.println(socketAddress.getAddress()); System.out.println(socketAddress.getHostName()); // 地址 System.out.println(socketAddress.getPort()); // 端口 } }
-
通信协议
协议: 约定, 就比如我们现在要说普通话
**网络通信协议: ** 速率, 传输码率, 代码结构, 传输控制...
问题: 非常的复杂
大事化小: 分层
TCP/IP协议簇: 实际上是一组协议
重要:
- TCP: 用户传输协议
- UDP: 用户数据报协议
出名的协议:
- TCP:
- IP: 网络互联协议
TCP UDP对比
TCP: 打电话
- 连接, 稳定
三次握手
四次挥手
三次握手: 加起来总共回复三次
最少需要三次才能保证稳定连接
A: 你瞅啥?
B: 瞅你咋地?
A: 干一场!
四次挥手: 加起来总共回复四次
A: 我要走了
B: 你要走了吗?
B: 你真的要走了吗?
A: 我真的要走了
- 客户端, 服务端
- 传输完成, 断开连接, 效率低
UDP: 发短信
- 不连接, 不稳定
- 客户端, 服务端: 没有明确的界限
- 不管有没有准备好, 都可以发给你...能不能接收到看造化
- 导弹
- DDOS: 洪水攻击(饱和攻击) 发了一大堆没有用的垃圾包 造成端口堵塞 网络炸了
TCP
客户端
- 连接服务器 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 length;
while ((length = is.read(buffer)) != -1){
baos.write(buffer,0,length);
}
System.out.println(baos.toString());
}
/*
byte[] buffer = new byte[1024];
int length;
while ((length = is.read(buffer)) != -1){
String msg = new String(buffer, 0, length);
System.out.println(msg);
}
*/
} 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) {
ServerSocket serverSocket = null;
Socket socket = null;
InputStream is = null;
FileOutputStream fos = null;
try {
//1、创建服务
serverSocket = new ServerSocket(9000);
//2、监听客户端的连接
socket = serverSocket.accept(); //阻塞式监听,会一直等待客户端连接。比如Scanner监听键盘输入
//3、获取输入流
is = socket.getInputStream();
//4、文件输出
fos = new FileOutputStream("img.png");
byte[] buffer = new byte[1024];
int length;
while ((length = is.read(buffer)) != -1){
fos.write(buffer,0,length);
}
//通知客户端我接收完毕了
OutputStream os = socket.getOutputStream();
os.write("我接收完毕了,你可以断开了".getBytes());
} catch (IOException e) {
e.printStackTrace();
}finally {
if (fos != null){
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (is != null){
try {
is.close();
} catch (IOException e) {
}
}
if (socket != null){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (serverSocket != null){
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
客户端
// 客户端
public class TcpClientDemo02 {
public static void main(String[] args) {
Socket socket = null;
OutputStream os = null;
FileInputStream fis = null;
ByteArrayOutputStream baos = null;
InputStream inputStream = null;
try {
//1、创建一个socket连接
socket = new Socket(InetAddress.getByName("127.0.0.1"), 9000);
//2、创建一个输出流
os = socket.getOutputStream();
//3、读取文件
File file = new File("D:\\ideaProgram\\Internet\\study\\img.png");
fis = new FileInputStream(file);
//4、写出文件
byte[] buffer = new byte[1024];
int length;
while ((length = fis.read(buffer)) != -1){
os.write(buffer,0,length);
}
// 通知服务器 我已经结束了
socket.shutdownOutput(); // 我已经传输完了
//确定服务器接收完毕,才能够断开连接
inputStream = socket.getInputStream();
//String byte[]
baos = new ByteArrayOutputStream();
byte[] buffer2 = new byte[1024];
int length2;
while ((length2 = inputStream.read(buffer2)) != -1){
baos.write(buffer2,0,length2);
}
System.out.println(baos.toString());
} catch (IOException e) {
e.printStackTrace();
}finally {
if (baos != null){
try {
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (inputStream != null){
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fis != null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (os != null){
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket != null){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
Tomcat
服务端
- 自定义 S
- Tomcat服务器 S:我们以后的重心在 java后台开发
客户端
- 自定义 C
- 浏览器 B
UDP
发短信:不用知道对方的地址
发送消息
发送端
// 不需要连接服务器
public class UdpClientDemo01 {
public static void main(String[] args) throws Exception {
//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 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();
}
}
咨询
循环发送消息
public class UdpSenderDemo01 {
public static void main(String[] args) throws Exception {
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 Exception {
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();
}
}
在线咨询
两个人都可以是发送方,也都可以是接收方
URL
统一资源定位符:定位资源的,定位互联网上的某个资源
DNS域名解析 www.baidu.com xxx.xx.x 本质上是一个IP
协议://IP地址:端口/项目名/资源
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了