网络编程
1.1概述
信件
计算机网络:
计算机网络是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统。
网络编程的目的:
无线电台…传播交流信息,数据交换.通信
想要达到这个效果需要什么:
- 如何准确的定位网络上的一台主机, 192.168.1.110:端口,定位到这个计算机上的某个资源
- 找到了这个主机,如何传输数据呢?
javaweb:网页开发 B/S 浏览器
网络编程:TCP/IP C/S 客户端
1.2网络通信的要素
如何实现双方的地址?
通信双方地址:
- ip
- 端口号
- 192.168.16.110:8080
规则:网络通信的协议:
TCP/IP参考模型:
小结:
- 网络编程中有两个主要的问题:
- 如何准确的定位到网络上的一台或者多台主机
- 找到主机之后如何进行通信
- 网络编程中的要素
- IP和端口号 IP
- 网络通信协议 udp,tcp
- 万物皆对象
1.3 IP
- ip地址:InetAddress
- 唯一定位一台忘了上计算机
- 127.0.0.1 本机的 localhost
- ip地址的分类
- IP地址分类:IPV4/ IPV6
- IPV4127.0.0.1,4个字节组成.0~255,42亿;30亿都在北美,亚洲4亿,2011年就用完了;
- IPV6ABCD:EF01:2345:6789:ABCD:EF01:2345:6789 , 128位。8个无符号整数! - 公网(互联网)和私网(局域网)
- 192.168.xx.xx 局域网 专门给组织内部使用的
- ABCD类地址
- IP地址分类:IPV4/ IPV6
- 域名:记忆Ip问题!
- IP:www.baiud.com
package com.hezhichao;
import java.net.InetAddress;
import java.net.UnknownHostException;
public class TestInetAddress {
public static void main(String[] args) {
try {
//查询本机地址
InetAddress inetAddress=InetAddress.getByName("127.0.0.1");
System.out.println(inetAddress);
InetAddress inetAddress3=InetAddress.getByName("localhost");
System.out.println(inetAddress3);
InetAddress inetAddress4=InetAddress.getLocalHost();
System.out.println(inetAddress4);
//查询网站ip地址
InetAddress inetAddress2=InetAddress.getByName("www.baidu.com");
System.out.println(inetAddress2);
//常用方法
System.out.println(inetAddress2.getAddress());//数组的地址
System.out.println(inetAddress2.getCanonicalHostName());//规范的名字
System.out.println(inetAddress2.getHostAddress());//ip
System.out.println(inetAddress2.getHostName());//域名,或者自己电脑的名字
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
}
1.4 端口
端口表示计算机上的一个程序的进程;
- 不同的进程有不同的端口号!用来区分软件的
- 被规定0~65535
- TCp,UDP: 65535 tcp:80,utp:80,单个协议下,端口号不能冲突
- 端口分类
- 公有端口0~1023
- HTTP:80
- HTTPS:443
- FTP:21
- Telen:23
- 程序注册端口:1024~49151,分配用户或者程序
- Tomcat:8080
- MYSQL:3306
- Oracle:1521
- 动态、私有:49152~65535
netstat -ano
查看本机所有端口netstat -aon|findstr "80""
查看指定端口
- 公有端口0~1023
package com.hezhichao;
import java.net.InetSocketAddress;
public class TestInetSocketAddress {
public static void main(String[] args) {
InetSocketAddress inetSocketAddress=new InetSocketAddress("127.0.0.1",8080);
InetSocketAddress inetSocketAddress2=new InetSocketAddress("localhost",8080);
System.out.println(inetSocketAddress);// /127.0.0.1:8080
System.out.println(inetSocketAddress2);// localhost/127.0.0.1:8080
System.out.println(inetSocketAddress.getAddress()); // /127.0.0.1
System.out.println(inetSocketAddress.getHostName());// 127.0.0.1 地址
System.out.println(inetSocketAddress.getHostString());// 127.0.0.1
System.out.println(inetSocketAddress.getPort()); // 8080 端口
}
}
1.5 通信协议
协议:约定,就好比我们现在说的普通话
网络通信协议: 速率,传输码率,代码结构,传输控制…
问题:非常的复杂?
大事化小:分层!
TCP/IP协议
重要:
- TCP:用户传输协议
- UDP:用户数据报协议
出名的协议: - TCP:
- IP:网络互连协议
TCP UDP 对比
TCP:打电话
- 连接,稳定
- 三次握手,四次挥手
最少需要三次,保证稳定连接!
A: 你瞅啥?
B: 瞅你咋地?
A:干一场!
连接需要四次来确认已经断开
A:我要走了
B:你真的要走了吗?
B:你真的走了吗?
A:我真的走了
- 客户端、服务端
- 传输完成,释放连接,效率低
UDP:发短信 - 不连接,不稳定
- 客户端、服务端:没有明确的界限
- 不管有没有准备好,都可以发给你
- 导弹
- DDOS:洪水攻击!(饱和攻击)
1.6 TCP
客户端:
1.连接服务器 Socket
2.发送信息
package com.hezhichao01;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
//客户端
public class TcpServerDemo01 {
public static void main(String[] args) {
Socket socket =null;
OutputStream os =null;
try {
//1.要知道服务器的地址
InetAddress serverIp= InetAddress.getByName("127.0.0.1");
//2.端口号
int port=9999;
//创建一个socke连接
socket = new Socket(serverIp,port);
//发送信息IO流
os = socket.getOutputStream();
os.write("你好,这里是我的战场".getBytes());
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
if (os!=null){
os.close();
}
if (socket!=null) {
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
服务器:
1.建立服务的端口 ServerSocket
2.等待连接用户的 accept
3.接收用的信息
package com.hezhichao01;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
//服务端
public class TcpDemo01 {
public static void main(String[] args) {
ServerSocket serverSocket =null;
Socket socket =null;
InputStream is=null;
ByteArrayOutputStream by=null;
//1.得有一个地址
try {
serverSocket = new ServerSocket(9999);
//等待客户端连接过来
socket =serverSocket.accept();
//读取信息
is = socket.getInputStream();
//使用管道流过滤,避免因为传输中文乱码
byte[] bytes = new byte[1024];
int len;
while((len= is.read(bytes))!=-1){
by.write(bytes,0,len);
}
System.out.println(by.toString());
} catch (IOException e) {
e.printStackTrace();
}finally {
//关闭流 先开后关
try {
if (by!=null){
by.close();
}
if (is!=null){
is.close();
}
if (socket!=null){
socket.close();
}
if (serverSocket!=null){
serverSocket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
TCP:
文件上传:
图片传输
package com.cs;
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
/**
* @Author:hzc 服务器端
* @dATE:2023/5/4 000419:50
*/
public class TcpDemo {
public static void main(String[] args) throws Exception{
InetAddress address=InetAddress.getLocalHost();
System.out.println(address.getHostAddress());
//1.创建一个Socket连接
Socket socket=new Socket(InetAddress.getByName("192.168.28.18"),10100);
//2.创建一个输出流
OutputStream on=socket.getOutputStream();
//3.文件流
FileInputStream fileInputStream=new FileInputStream(new File("1.jpg"));
//4.写出文件
byte[] bytes = new byte[1024];
int len = 0;
while ((len=fileInputStream.read(bytes))!=-1){
on.write(bytes,0,len);
}
//通知服务器,我已经结束了
socket.shutdownOutput();//我已经传输完毕
//确定服务器接收完毕才能断开连接
InputStream inputStream=socket.getInputStream();
ByteArrayOutputStream baos=new ByteArrayOutputStream();
byte[] bytes2 =new byte[1024];
int len2 = 0;
while ((len2=inputStream.read(bytes2))!=-1){
baos.write(bytes,0,len2);
}
if (baos.equals(200)){
baos.close();
inputStream.close();
fileInputStream.close();
on.close();
socket.close();
}
//关闭资源
}
}
package com.cs;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
* @Author:hzc 客户端
* @dATE:2023/5/4 000420:17
*/
public class TcpServerDemo {
public static void main(String[] args) throws Exception{
//1 创建端口
ServerSocket server= new ServerSocket(9000);
//2.监听客户端连接
Socket socket=server.accept();//阻塞式监听,会一直等待客户端连接
//3.获取输入流
InputStream stream=socket.getInputStream();
//4.文件输出
FileOutputStream fos=new FileOutputStream(new File("2.jpg"));
byte[] bytes = new byte[1024];
int len;
while ((len=stream.read(bytes))!=-1){
fos.write(bytes,0,len);
}
OutputStream outputStream=socket.getOutputStream();
outputStream.write(200);
//关闭资源
socket.close();
fos.close();
server.close();
stream.close();
}
}
Tomcat
服务器
- Tomcat 服务器 S
客户端
- 浏览器 B
1.7 UDP
发短信:不需要连接,需要知道地方的地址!
package com.cs;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
/**
* @Author:hzc 发送消息
* @dATE:2023/5/5 000519:57
*/
//不需要连接服务器
public class Demo3 {
public static void main(String[] args) throws Exception{
//1.建立一个Socket
DatagramSocket datagramSocket = new DatagramSocket();
//发送给谁
InetAddress localhost=InetAddress.getByName("localhost");
int port=9090;
//2.建一个包 DatagramPacket
String msg="hello";
//方法参数 数据,从什么位置开始,哪个位置停止,对方ip,对方端口
DatagramPacket packet= new DatagramPacket(msg.getBytes(), 0,msg.getBytes().length,localhost,port);
//3.发送包
datagramSocket.send(packet);
//4.关闭流
datagramSocket.close();
}
}
package com.cs;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
/**
* @Author:hzc 接收消息
* @dATE:2023/5/5 000520:06
*/
public class UdpDemo2 {
public static void main(String[] args) throws Exception{
//开放端口
DatagramSocket datagramSocket=new DatagramSocket(9090);
//2.接收数据
byte[] bytes = new byte[1024];
DatagramPacket datagramPacket=new DatagramPacket(bytes, 0,bytes.length);//接收
datagramSocket.receive(datagramPacket);//阻塞接收
System.out.println(datagramPacket.getAddress());
System.out.println(new java.lang.String(datagramPacket.getData(),0,datagramPacket.getLength()));
//关闭
datagramSocket.close();
}
}
发送消息
package com.cs.chat;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
/**
* @Author:hzc 发送方
* @dATE:2023/5/5 000520:34
*/
public class UdpSenderDemo {
public static void main(String[] args) throws Exception {
DatagramSocket socket = new DatagramSocket(9090);
//输入流读取键盘输入
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
while (true){
String msg=bufferedReader.readLine();
DatagramPacket packet = new DatagramPacket(msg.getBytes(), 0, msg.length(), new InetSocketAddress("localhost", 6666));
socket.send(packet);
String data2=new String(packet.getData(),0,packet.getLength());
if (data2.equals("404")){
break;
}
// byte[] bytes = new byte[1024];
// DatagramPacket datagramPacket = new DatagramPacket(bytes, 0, bytes.length);
// socket.receive(datagramPacket);//阻塞接收
// String data=new String(datagramPacket.getData(),0,datagramPacket.getLength());
// if (data.equals("404")){
// break;
// }
}
socket.close();
}
}
package com.cs.chat;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
/**
* @Author:hzc 接收方
* @dATE:2023/5/5 000520:35
*/
public class UdpsenderDemo1 {
public static void main(String[] args) throws Exception{
DatagramSocket socket = new DatagramSocket(6666);
//输入流读取键盘输入
while (true){
byte[] bytes = new byte[1024];
DatagramPacket datagramPacket = new DatagramPacket(bytes, 0, bytes.length);
socket.receive(datagramPacket);//阻塞接收
String data=new String(datagramPacket.getData(),0,datagramPacket.getLength());
System.out.println(data);
if (data.equals("404")){
break;
}
}
socket.close();
}
}
多线程发送消息
package Day.chat;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import static cn.hutool.cron.CronUtil.stop;
public class UpdataSenderDemo02 implements Runnable{
DatagramSocket socket=null;
BufferedReader bufferedReader=null;
private int port;
private String forip;
private int forport;
public UpdataSenderDemo02(int port, String forip, int forport) {
this.port = port;
this.forip = forip;
this.forport = forport;
try{
socket=new DatagramSocket(port);
}catch (Exception e){
e.printStackTrace();
}
}
@Override
public void run() {
while (true){
try{
bufferedReader=new BufferedReader(new InputStreamReader(System.in));
String Str=bufferedReader.readLine();
DatagramPacket packet=new DatagramPacket(Str.getBytes(),Str.length(), new InetSocketAddress(forip,forport));
socket.send(packet);
if (Str.equals("exit")){
break;
}
}catch (Exception e){
e.printStackTrace();
}
}
socket.close();
}
}
多线程接收消息
package Day.chat;
import java.io.BufferedReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import static cn.hutool.cron.CronUtil.stop;
public class UpdataReceiveDemo2 implements Runnable{
DatagramSocket socket=null;
DatagramPacket packet=null;
private int port;
private String name;
public UpdataReceiveDemo2(int port,String name) {
this.port = port;
this.name = name;
try{
socket=new DatagramSocket(port);
packet = new DatagramPacket(new byte[1024], 1024);
}catch (Exception e){
e.printStackTrace();
}
}
@Override
public void run() {
while (true){
try{
socket.receive(packet);
String info = new String(packet.getData(), 0, packet.getLength());
System.out.println(name+":"+info);
if (info.equals("exit")){
break;
}
}catch (Exception e){
e.printStackTrace();
}
}
socket.close();
}
}
通过调用开始实体类达到两个可以互相发信息
public static void main(String[] args) {
new Thread(new UpdataSenderDemo02(9999,"127.0.0.1",9998)).start();
new Thread(new UpdataReceiveDemo2(9997,"学生")).start();
}
public static void main(String[] args) {
new Thread(new UpdataSenderDemo02(9995,"127.0.0.1",9997)).start();
new Thread(new UpdataReceiveDemo2(9998,"老师")).start();
}
1.8 URL(路径)
https://www.baidu.com/
统一资源定位符:定位资源的,定位互联网上的某一个资源
DNS域名解析 www.baidu.com XXX.x.x.x
- 协议://ip地址: 端口/项目名字 /资源http://121.40.229.97:10100/jxmq/