网络编程
1.1、概述
地球村:
对地球的一种比喻说法。现代科技的迅速发展,缩小了地球上的时空距离,国际交往日益频繁便利,因而整个地球就如同是茫茫宇宙中的一个小村落。
计算机网络:
是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统。
网络编程的目的:
无线电台…传播交流信息,数据交换。通信。
想要达到的效果需要什么:
- 如何准确的定位网络上的一台电脑 192.168.16.124:端口,定位到这个计算机上的某个资源。
- 找到这个主机,如何传输数据呢?
javaweb:网页编程 BS
网络编程:TCP/IP CS
1.2、网络通信的要素
如何实现网络通信?
需要知道通信双方地址:
- ip 192.168.1.1
- 端口号
- 192.168.16.24:5900
规则:网络通信协议
TCP/IP 参考模型
小结:
- 网络编程中有两个主要问题
- 如何准确定位到网络上的一台或者多台主机
- 找到主机之后如何进行通信
- 网络编程中的要素
- ip和端口号 ip
- 网络通信协议 udp,tcp
- 万物皆对象
1.3、IP
ip地址:InetAddress
-
唯一定位一台计算机
-
127.0.01:本机localhost
-
ip地址分类
-
ipv4/ipv6地址分类
- IPV4 127.0.0.1 ,4个字节组成,1个字节8位。0-255,42亿~;30亿都在北美,亚洲4亿,2011年就用尽了。
- IPV6 fe80::e574:5dfc:4204:8875%11,16个字节,128位。8个无符号整数。
2001:0bb2:aaa:0015:0000:0000:1aaa:1312 每个数字都是16进制,一个十六进制数可以写成4个二进制数(就是占4位)。共32个数字*4位=128
-
公网(互联网)-私网(局域网)
-
ABCD类地址
-
192.168.xx.xx ,专门给组织内部使用的。
-
-
-
域名:记忆IP问题!
- IP:www.vip.com 万网
import java.net.UnknownHostException;public class TestInetAddress {
public static void main(String[] args) {
try {
//查询本地地址InetAddress byName = InetAddress.getByName("127.0.0.1");System.out.println(byName);//查询网站ip地址InetAddress byName1 = InetAddress.getByName("www.baidu.com");System.out.println(byName1);//常用方法System.out.println(byName1.getAddress());System.out.println(byName1.getCanonicalHostName());//规范的名字System.out.println(byName1.getHostAddress());//ipSystem.out.println(byName1.getHostName());//域名,或者自己的电脑的额名字} catch (UnknownHostException e) {
e.printStackTrace();}}}
1.4、端口
端口表示计算机上的一个程序的进程。
-
不同进程有不同的端口号!用来区分软件!
-
端口被规定范围:0~65535
-
TCP,UDP:这两个都有65535这么多端口,即65535*2。tcp:80,udp:80.单个协议下,端口号不能冲突。
-
端口分类
-
公有端口0-1023
- HTTP默认端口:80
- HHTPS默认端口:443
- FTP:21
- Telent:23
-
程序注册端口:1024~49151,非陪用户或者程序
- Tomcat:8080
- MySQL:3306
- Oracle:1521
-
动态、私有:49152-65535
netstat -ano 命令:可以查看本机开放的全部端口。
- LISTENING时表示处于侦听状态,就是说该端口是开放的,等待连接,但还没有被连接。就像
你房子的门已经敞开的,但还没有人进来。 - ESTABLISHED的意思是建立连接。表示两台机器正在通信。
- CLOSE_WAIT 对方主动关闭连接或者网络 异常导致连接中断。
- TIME_WAIT 我方主动调用close()断开连接,收到对方确认后状态变为TIME_WAIT。
netstat -ano|findstr "5900":查看5900端口详情。 tasklist|findsr "8696" :查看指定端口的进程。(或者电脑任务管理器里面的PID栏查看)
public class TestInetSocktaddress { 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);System.out.println(inetSocketAddress2);System.out.println(inetSocketAddress.getAddress());System.out.println(inetSocketAddress.getHostName());//hosts文件可以配置映射地址System.out.println(inetSocketAddress.getPort());//端口} }
- LISTENING时表示处于侦听状态,就是说该端口是开放的,等待连接,但还没有被连接。就像
-
1.5、通信协议
协议:约定,就好比我们现在说的是普通话。
**网络通信协议:**速率,传输码率,代码结构,传输控制。。。
**问题:**非常的复杂
大事化小:分层!
TCP/IP协议簇:实际上是一组协议
重要:
- TCP:用户传输协议。
- UDP:用户数据报协议。
出名的协议:
- TCP:用户传输协议。
- IP:网络互联协议。
TCP和UDP对比:
TCP:打电话
- 连接,稳定
- 三次握手,四次挥手。
最少需要三次,保证稳定连接!
A:你瞅啥?
B:瞅你咋地?
A:干一场!四次挥手:
A:我要走了
B:你真的要走了吗?
B:你真的真的要走了吗?
A:我真的要走了!
- 客户端,服务端
- 传输完成,释放连接,效率低
UDP:发短信
- 不连接,不稳定。
- 客户端、服务端:没有明确的界限。
- 不管有没有准备好,都可以发给你。
- 导弹攻击
- DDOS:洪水攻击!(饱和攻击)
1.6、TCP
客户端
- 连接服务器 Socket
- 发送消息
//客户端
public class TcpClientDemo01 {
public static void main(String[] args) {
Socket socket=null;OutputStream outputStream=null;try {
//1.要知道服务器的地址、端口号InetAddress serverIp=InetAddress.getByName("127.0.0.1");int port=9999;//2.创建一个socket连接socket = new Socket(serverIp,port);//3.发送消息 IO流outputStream = socket.getOutputStream();outputStream.write("你好,欢迎学习java".getBytes());} catch (Exception e) {
e.printStackTrace();}finally {
if (outputStream!=null){
try {
outputStream.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 inputStream = null;ByteArrayOutputStream baos = null;try {
//1.我得有一个地址serverSocket = new ServerSocket(9999);while (true){
//2.等待客户端连接过来socket = serverSocket.accept();//3.读取客户端的消息inputStream = socket.getInputStream();//管道流baos = new ByteArrayOutputStream();byte[] buffer = new byte[1024];int len;while ((len = inputStream.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 (inputStream != null) {
try {
inputStream.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 inputStream = null;FileOutputStream baos = null;OutputStream outputStream = null;try {
//1.创建服务serverSocket = new ServerSocket(9000);//2.监听客户端连接//阻塞式监听,会一直等待客户端连接socket = serverSocket.accept();//3.读取客户端的消息//获取输入流inputStream = socket.getInputStream();//4.文件输出,利用管道流baos = new FileOutputStream(new File("jyw123.jpg"));byte[] buffer = new byte[1024];int len;//每次读取一个字节while ((len = inputStream.read(buffer)) != -1) {
baos.write(buffer, 0, len);}//通知客户端接收完毕outputStream = socket.getOutputStream();outputStream.write("我接受完毕了,你可以断开了".getBytes());} catch (IOException e) {
e.printStackTrace();} finally {
//关闭资源if (outputStream != null) {
try {
outputStream.close();} catch (IOException e) {
e.printStackTrace();}}if (baos != null) {
try {
baos.close();} catch (IOException e) {
e.printStackTrace();}}if (inputStream != null) {
try {
inputStream.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 TcpClientDemo02 {
public static void main(String[] args) {
//1。创建一个Socket连接Socket socket = null;try {
socket = new Socket(InetAddress.getByName("127.0.0.1"),9000);//2.创建一个输出流OutputStream outputStream = socket.getOutputStream();//3.文件流FileInputStream fileInputStream = new FileInputStream(new File("F:\\worksapce\\wlbc-study\\src\\123.jpg"));//4.写出文件byte[] buffer = new byte[1024];int len;// read (byte[] b) 方法, 从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。以整数形式返回实际读取的字节数。while ((len=fileInputStream.read(buffer))!=-1){
outputStream.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();fileInputStream.close();outputStream.close();socket.close();} catch (IOException e) {
e.printStackTrace();}}
}
Tomcat
服务端
- 自定义S
- Tomcat服务器S
客户端
- 自定义 C
- 浏览器 B
1.7、UDP
发短信:不用连接,需要知道对方的地址!
发送消息:
public class UdpClientDemo1 {
public static void main(String[] args) throws Exception {
//1.建立一个SocketDatagramSocket 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 UdpServerDemo1 {
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 UdpSendDemo01 {
public static void main(String[] args) throws Exception {
DatagramSocket socket = new DatagramSocket(8888);//准备数据:读取控制台Ststem.inBufferedReader reader = new BufferedReader(new InputStreamReader(System.in));while (true) {
String data = reader.readLine();byte[] dates = data.getBytes();DatagramPacket packet = new DatagramPacket(dates, 0, dates.length, new InetSocketAddress("localhost", 6666));System.out.println(dates.length);//bye:3System.out.println(packet.getLength());//bye:3socket.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) {
//准备接收包裹,放到container里面byte[] container = new byte[1024];System.out.println(container.length);//1024DatagramPacket packet = new DatagramPacket(container, 0, container.length);System.out.println(packet.getLength());//1024socket.receive(packet);//阻塞式接收包裹。上面是1024,下面是3,说明receive方法将他改变了System.out.println(packet.getLength());//3//断开连接bytebyte[] data = packet.getData();//1024//String receiveData = new String(data, 0, data.length);//1024String receiveData = new String(data, 0, packet.getLength());//我不需要固定数组container那么长(1024),我只需要packet里面数据长度(3),这样写后面的equals判断不需要写trim()System.out.println(packet.getLength());//收到的是长度是3System.out.println(data.length);//1024System.out.println(receiveData.length());//3System.out.println(receiveData);if (receiveData.trim().equals("bye")) {
break;}}socket.close();}
}
在线咨询:两个人都可以发送方,也都可以是接收方!
多线程互相聊天
发送类工具
//发送线程
public class TalkSend implements Runnable{
DatagramSocket socket =null;BufferedReader reader =null;private String toIp;private int fromPort;private int toPort;public TalkSend(int fromPort,String toIp, int toPort) {
this.toIp = toIp;this.fromPort = fromPort;this.toPort = toPort;try {
socket =new DatagramSocket(fromPort);reader = new BufferedReader(new InputStreamReader(System.in));} catch (Exception e) {
e.printStackTrace();}}@Overridepublic void run() {
while (true) {
try {
String data = reader.readLine();DatagramPacket packet = new DatagramPacket(data.getBytes(), 0, data.getBytes().length, new InetSocketAddress(this.toIp, this.toPort));socket.send(packet);if (data.equals("bye")) {
break;}} catch (Exception e) {
e.printStackTrace();}}socket.close();}
}
接受类工具
//接收线程
public class TalkReceive implements Runnable{
DatagramSocket socket =null;private int port;private String msgFrom;//消息来源public TalkReceive(int port,String msgFrom) {
this.port = port;this.msgFrom = msgFrom;try {
socket = new DatagramSocket(port);} catch (SocketException e) {
e.printStackTrace();}}@Overridepublic void run() {
while (true) {
try {
//准备接收包裹,放到container里面byte[] container = new byte[1024];DatagramPacket packet = new DatagramPacket(container, 0, container.length);socket.receive(packet);//阻塞式接收包裹。上面是1024,下面是3,说明receive方法将他改变了//断开连接byteString receiveData = new String(packet.getData(), 0, packet.getLength());System.out.println(msgFrom+":"+receiveData);if (receiveData.trim().equals("bye")) {
break;}} catch (IOException e) {
e.printStackTrace();}}socket.close();}
}
学生端启动类
public class TalkStudent {
public static void main(String[] args) {
//开启两个线程new Thread(new TalkSend(7777,"localhost",9999)).start();new Thread(new TalkReceive(8888,"老师")).start();}
}
老师类启动端
public class TalkTeacher {
public static void main(String[] args) {
//开启两个线程new Thread(new TalkSend(5555,"localhost",8888)).start();new Thread(new TalkReceive(9999,"学生")).start();}
}
1.8、URL
https://www.baidu.com/
统一资源定位符:定位资源,定位互联网上的某一资源。
DNS域名解析:将https://www.baidu.com/解析成xxx.x…x…x
本质是把域名解析成ip
基本上5部分组成:
协议://IP地址:端口/项目名/对应资源
public class URLDown {
public static void main(String[] args) throws Exception {
//1.下载地址URL url = new URL("https://m10.music.126.net/20200919161055/7963703b1af08b9d00a2e6ce2ba6c981/yyaac/obj/wonDkMOGw6XDiTHCmMOi/3918591949/c8a1/cba7/c6ea/5a3677569928db9f736580e5a2107f55.m4a");HttpsURLConnection httpURLConnection=(HttpsURLConnection)url.openConnection();InputStream inputStream = httpURLConnection.getInputStream();FileOutputStream fileOutputStream = new FileOutputStream("f.m4a");byte[] bytes = new byte[1024];int len;if ((len=inputStream.read(bytes))!=-1){
fileOutputStream.write(bytes,0,len);//写出这个数据}fileOutputStream.close();inputStream.close();httpURLConnection.disconnect();//断开连接}
}