第二十七天:网络编程
计算机科学就是有关计算机的,正如天文学就是有关望远镜的。
【狂神说Java】网络编程详解_哔哩哔哩_bilibili
学习内容
计算机网络
计算机网络是指将地理位置不同的具有独立功能的多台让过及其外部设备 , 通过通信线路连接起来在网络操作系统, 网络管理软件及网络通信协议的管理和协调下 , 实现源共皇和信息传递的计算机系统 。
如何定位
-
如何精确定位到网络上的一台主机:192.168.16.124。端口:定位到这个计算机上的某个资源
-
找到了这个主机,如何传输数据?
JavaWeb开发:网页编程 B/S
网络编程:TCP/IP C/S
网络通信的要素
如何实现网络的通信?
通信双方的地址
规则:网络通信的协议
http,ftp,https,tcp等
TCP/IP参考模型
IP地址InetAddress
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| package com.joker_yue.javalearn.NetLearn;
import java.net.Inet4Address; import java.net.InetAddress; import java.net.UnknownHostException;
public class InetAddressTest { public static void main(String[] args) { try { InetAddress InetAddress1 = Inet4Address.getByName("127.0.0.1"); System.out.println(InetAddress1); InetAddress InetAddress3 = Inet4Address.getByName("localhost"); System.out.println(InetAddress3); InetAddress InetAddress4 = Inet4Address.getLocalHost(); System.out.println(InetAddress4);
InetAddress InetAddress2 = Inet4Address.getByName("www.baidu.com"); System.out.println(InetAddress2);
System.out.println(InetAddress2.getAddress()); System.out.println(InetAddress2.getCanonicalHostName()); System.out.println(InetAddress2.getHostAddress()); System.out.println(InetAddress2.getHostName());
} catch (UnknownHostException e) { throw new RuntimeException(e); } } }
|
端口Port
端口表示计算机上的一个程序的进程:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| package com.joker_yue.javalearn.NetLearn;
import java.net.InetAddress; import java.net.InetSocketAddress;
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。IP:网络互联协议
TCP UDP对比
-
TCP:打电话
-
连接:稳定
-
三次握手,四次挥手
-
客户端、服务端
-
传输完成就会释放连接,效率低
1 2 3 4 5 6 7 8
| A:你瞅啥 B:瞅你咋地 A:干一架?
A:我要走了 B:你真的要走了吗 A:我真的要走了 B:你真的要走了
|
-
UDP:发短信
- 不连接,不稳定
- 客户端、服务端没有明确的界限
- 不管有没有准备好,都可以发给你
- DDOS:洪水攻击(饱和攻击),就是给端口发送一大堆无用数据包,造成端口堵塞
TCP
客户端
-
连接服务器Socket
-
发送消息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| package com.joker_yue.javalearn.NetLearn;
import java.io.IOException; import java.io.OutputStream; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException;
public class TCPClientDemo01 { public static void main(String[] args) { Socket socket = null; OutputStream os = null; try { InetAddress severIP = InetAddress.getByName("127.0.0.1"); int port = 9999; socket = new Socket(severIP, port); os = socket.getOutputStream(); os.write("你好!".getBytes());
} catch (UnknownHostException e) { throw new RuntimeException(e); } catch (IOException e) { throw new RuntimeException(e); } finally { if (os != null) { try { os.close(); } catch (IOException e) { throw new RuntimeException(e); } } if (socket != null) { try { socket.close(); } catch (IOException e) { throw new RuntimeException(e); } } } } }
|
服务端
-
建立服务端口serverSocket
-
等待用户的连接 accept
-
接收用户的消息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
| package com.joker_yue.javalearn.NetLearn;
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) { ServerSocket serverSocket = null; Socket socket = null; InputStream is = null; ByteArrayOutputStream baos = null; try { serverSocket = new ServerSocket(9999); socket = serverSocket.accept(); 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) { throw new RuntimeException(e); } finally { if (baos != null) {
try { baos.close(); } catch (IOException e) { throw new RuntimeException(e); } } if (is != null) { try { is.close(); } catch (IOException e) { throw new RuntimeException(e); } } if (socket != null) { try { socket.close(); } catch (IOException e) { throw new RuntimeException(e); } } if (serverSocket != null) { try { serverSocket.close(); } catch (IOException e) { throw new RuntimeException(e); } }
} } }
|
文件上传
客户端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| package com.joker_yue.javalearn.NetLearn;
import java.io.*; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException;
public class TCPClientDemo02 { public static void main(String[] args) throws IOException { Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 9000); OutputStream os = socket.getOutputStream();
FileInputStream fis = new FileInputStream(new File("log.txt")); byte[] buffer = new byte[1024]; int len; while ((len = fis.read()) != -1) { os.write(buffer,0,len); }
socket.shutdownOutput();
InputStream is = socket.getInputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer2 = new byte[1024]; int len2; while((len2= is.read(buffer2))!=-1){ baos.write(buffer2,0,len2); } System.out.println(baos.toString());
baos.close(); fis.close(); os.close(); socket.close(); } }
|
服务端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| package com.joker_yue.javalearn.NetLearn;
import java.io.*; import java.net.ServerSocket; import java.net.Socket;
public class TCPServerDemo02 { public static void main(String[] args) throws IOException { ServerSocket serverSocket = new ServerSocket(9000); Socket socket = serverSocket.accept(); InputStream is = socket.getInputStream(); FileOutputStream fos = new FileOutputStream(new File("receive")); 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(); } }
|
Tomcat
服务端
客户端
UDP
发短信:不用连接,需要知道对方的地址
发送消息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| package com.joker_yue.javalearn.NetLearn;
import java.io.IOException; import java.net.*;
public class UDPClientDemo01 { public static void main(String[] args) throws IOException { DatagramSocket socket = new DatagramSocket(); String msg = "你好,服务器!"; InetAddress localhost = InetAddress.getByName("localhost"); int port = 9090; DatagramPacket datagramPacket = new DatagramPacket(msg.getBytes(),0,msg.getBytes().length,localhost,port); socket.send(datagramPacket); socket.close(); } }
|
接收后端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| package com.joker_yue.javalearn.NetLearn;
import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.SocketException;
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();
} }
|
UDP聊天实现
发送端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| package com.joker_yue.javalearn.NetLearn;
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetSocketAddress; import java.net.SocketException;
public class UDPSender { public static void main(String[] args) throws IOException { DatagramSocket socket = new DatagramSocket(8888);
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(); } }
|
接收端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| package com.joker_yue.javalearn.NetLearn;
import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.SocketException;
public class UDPReceiver { 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);
byte[] data = packet.getData(); String receiverData = new String(data, 0, packet.getLength()); System.out.println(receiverData);
if (receiverData.equals("bye")) { break; }
} socket.close(); } }
|
在线咨询:两个人都可以是发送方,也可以是接收方
写好接收端和发送端先
发送端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| package com.joker_yue.javalearn.NetLearn;
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetSocketAddress; import java.net.SocketException;
public class TalkSender implements Runnable {
DatagramSocket socket = null; BufferedReader reader = null;
private int fromPort; private String toIP; private int toPort;
public TalkSender(int fromPort, String toIP, int toPort) { this.fromPort = fromPort; this.toIP = toIP; this.toPort = toPort;
try { socket = new DatagramSocket(fromPort); reader = new BufferedReader(new InputStreamReader(System.in)); } catch (SocketException e) { throw new RuntimeException(e); }
}
@Override public void run() {
while (true) { try { String data = reader.readLine(); byte[] datas = data.getBytes(); DatagramPacket packet = new DatagramPacket(datas, 0, datas.length, new InetSocketAddress(this.toIP, this.toPort));
socket.send(packet); if (data.equals("bye")) { break; } } catch (IOException e) { throw new RuntimeException(e); }
} socket.close(); } }
|
接收端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| package com.joker_yue.javalearn.NetLearn;
import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.SocketException;
public class TalkReceiver implements Runnable { DatagramSocket socket = null;
private int port; private String msgFrom;
public TalkReceiver(int port,String msgFrom) { this.port = port; this.msgFrom = msgFrom; try { socket = new DatagramSocket(port); } catch (SocketException e) { throw new RuntimeException(e); } }
@Override public void run() {
while (true) {
try { byte[] container = new byte[1024]; DatagramPacket packet = new DatagramPacket(container, 0, container.length); socket.receive(packet);
byte[] data = packet.getData(); String receiverData = new String(data, 0, packet.getLength()); System.out.println(msgFrom+":"+receiverData);
if (receiverData.equals("bye")) { break; } } catch (IOException e) { throw new RuntimeException(e); }
} socket.close(); } }
|
创建两个身份
学生
1 2 3 4 5 6 7 8 9 10 11
| package com.joker_yue.javalearn.NetLearn;
public class TalkStudents { public static void main(String[] args) { new Thread(new TalkSender(7777,"localhost",9999)).start(); new Thread(new TalkReceiver(8888,"老师")).start();
} }
|
老师
1 2 3 4 5 6 7 8 9 10
| package com.joker_yue.javalearn.NetLearn;
public class TalkTeacher { public static void main(String[] args) { new Thread(new TalkSender(5555,"localhost",8888)).start(); new Thread(new TalkReceiver(9999,"学生")).start();
} }
|
URL
URL:统一资源定位符,用来定位资源的,定位互联网上的某一个资源
DNS域名解析:将www.baidu.com 解释为IP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| package com.joker_yue.javalearn.NetLearn;
import java.io.FileOutputStream; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL;
public class URLDownload { public static void main(String[] args) throws Exception { URL url = new URL("http://localhost:8080/Joker/Unknown.txt");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
InputStream is = urlConnection.getInputStream();
FileOutputStream fos = new FileOutputStream("Unknown.txt");
byte[] buffer = new byte[1024];
int len ; while ((len=is.read(buffer))!=-1){ fos.write(buffer,0, len); }
fos.close(); is.close(); urlConnection.disconnect();
} }
|