网络编程
概述
TCP
传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF的RFC 793 [1] 定义。
TCP旨在适应支持多网络应用的分层协议层次结构。 连接到不同但互连的计算机通信网络的主计算机中的成对进程之间依靠TCP提供可靠的通信服务。TCP假设它可以从较低级别的协议获得简单的,可能不可靠的数据报服务。 原则上,TCP应该能够在从硬线连接到分组交换或电路交换网络的各种通信系统之上操作。
UDP
[Internet ](https://baike.baidu.com/item/Internet /272794)协议集支持一个无连接的[传输协议](https://baike.baidu.com/item/传输协议/8048821),该协议称为用户数据包协议(UDP,User Datagram Protocol)。UDP 为应用程序提供了一种无需建立连接就可以发送封装的 IP 数据包的方法。RFC 768 [1] 描述了 UDP。
Internet 的传输层有两个主要协议,互为补充。无连接的是 UDP,它除了给应用程序发送数据包功能并允许它们在所需的层次上架构自己的协议之外,几乎没有做什么特别的事情。面向连接的是 TCP,该协议几乎做了所有的事情。 [2]
计算机网络:大三上会学,好好学哦
计算机网络是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及**网络通信协议**的管理和协调下,实现资源共享和信息传递的计算机系统。
网络编程目的:
传播信息、数据交换、资源 共享、
记得好好学计算机网络哦
网络通信
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1ZGqOEcm-1639882171401)(C:\Users\17730\AppData\Roaming\Typora\typora-user-images\image-20211212161142835.png)]
- 实现方法
- 通信双方地址: IP 端口号 192.192.16.192
小结
-
网络编程中有两个主要的问题
- 如何准确的定位到网络上的一台或多台主机
- 找到主机之后如何进行通信
-
网络编程中的要素
- IP和端口号
- 网络通信协议
-
万物皆对象
IP
IP地址:inetAddress
- 唯一定位一台网络的地址
- 127.0.0.1:本机
- ip地址的分类
- IPV4/IPV6(还没完全使用IPV6)
- 公网-私网
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4JWusCug-1639882171403)(C:\Users\17730\AppData\Roaming\Typora\typora-user-images\image-20211212162842209.png)]
IP地址范围:
A类IP地址 地址范围1.0.0.1-126.255.255.254(二进制表示为:00000001 00000000 00000000 00000001 - 01111110 11111111 11111111 11111110)。
B类IP地址地址范围128.1.0.1-191.254.255.254(二进制表示为:10000000 00000001 00000000 00000001 - 10111111 11111110 11111111 11111110)
C类IP地址范围192.0.1.1-223.255.254.254(二进制表示为: 11000000 00000000 00000001 00000001 - 11011111 11111111 11111110 11111110)。
D类IP地址范围224.0.0.1-239.255.255.254 。
E类IP地址范围240.0.0.0—255.255.255.254。
上述IP地址均为IPv4地址。
- 域名:记忆IP问题
- ip 挺贵的
地址查询
public class IPTest {
public static void main(String[] args) {
try{ InetAddress inetAddress1= InetAddress.getByName("127.0.0.1");
System.out.println(inetAddress1);//较快
InetAddress inetAddress2= InetAddress.getByName("www.baidu.com");//www.baidu.com/36.152.44.95较慢
System.out.println(inetAddress2);//较快
}catch (UnknownHostException e){
e.printStackTrace();
}}
}
//查询本机地址
InetAddress inetAddress1= InetAddress.getByName("127.0.0.1");
System.out.println(inetAddress1);//127.0.0.1
InetAddress inetAddress3= InetAddress.getByName("localhost");
System.out.println(inetAddress3);//localhost/127.0.0.1
InetAddress inetAddress4= InetAddress.getLocalHost();
System.out.println(inetAddress4);//是kimi呀/**.***.***.***(主机号)
端口
端口表示计算机上的程序进程;
-
不同的进度有不同的端口号。用来区分软件
-
被规定0-65535
-
TCP,UDP:65535*2 (TCP:80 也可 UDP:80 因为tcp和udp不是相同的协议,不冲突)单个协议下,端口号不能冲突
-
端口分类
-
公用端口 0-1023
- http :80
- https :43
- ftp :21
- SHS :22
- Telent :23
-
程序注册端口:2014-49151左右(程序一般用不完,分配给用户或程序)
- Tomcat:8080
- MySQL:3306
- Oracle:1521
-
私有、动态:49152-65535
(一个does的命令:1. netstat -ano查看端口
2.netstat -ano|findsre“某个pid”)
-
InetSocketAddress inetSocketAddress = new InetSocketAddress("127.0.0.1",8080) ;
System.out.println(inetSocketAddress);///127.0.0.1:8080
InetSocketAddress inetSocketAddress1 = new InetSocketAddress("localhost",8080) ;
System.out.println(inetSocketAddress1);//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.getPort());//8080
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aCWsUne3-1639882171404)(C:\Users\17730\AppData\Roaming\Typora\typora-user-images\image-20211214214852536.png)](狂神画的图)
通信协议
网络通信协议:[网络通信协议百度百科](网络通信协议_百度百科 (baidu.com))
网络通信协议:速率,传输码率、代码结构、传输控制…通信工程会学哦
通过分层解决
TCP/IP协议族
- TCP:用户传输协议
- UDP:用户数据报协议
出名的协议
- TCP:
- IP:网络互连协议
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5cGN5TIm-1639882171406)(C:\Users\17730\AppData\Roaming\Typora\typora-user-images\image-20211214220314338.png)]
TCP UDP 对比
TCP:连接打电话
- 连接,较稳定
- 三次握手、四次分手[三次握手、四次分手](简析TCP的三次握手与四次分手 - __Meng - 博客园 (cnblogs.com))(狂神的更易理解)
最少需要三次,保证稳定连接!
A:你瞅啥
B:瞅你咋地
A:来打一架
A:我断开了
B:你要断开了么
B:你真的要断开了么
A:嗯断开
- 客户端、服务端
- 传输完成、释放连接、效率低
UDP:不连接发短信
- 不稳定,不连接
- 客户端、服务端:没有明确的界限
- 不管有没有准备好,都可以发送,不能保证一定接受到
- DDOS:洪水攻击(饱和攻击)[FLOOD ATTACK](洪水攻击 - Search (bing.com))
TCP(打电话)
客户端
- 连接服务器Socket
- 发送消息
public class TcpClientDemo01 {
public static void main(String[] args) {
InetAddress serverIP;
Socket socket=null;
OutputStream os=null;
{
try {
//1.要知道服务器的端口
serverIP = InetAddress.getByName("127.0.0.1");
int port = 9999;
//2.创建一个Socket连接
socket = new Socket(serverIP,port);
// public Socket() {
// setImpl();
// }
//发送消息IO流
os=socket.getOutputStream();
os.write("阿娆真漂亮".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 inputStream=null;
ByteArrayOutputStream byteArrayOutputStream = null;
try {
//1.我的有一个地址
serverSocket = new ServerSocket(9999);
while (true) {
//2.等待客户端连接
socket = serverSocket.accept();
//3.读取客户端消息
inputStream = socket.getInputStream();
/*
io流复习
byte[] buffer = new byte[1024];
int len;
while ((len=inputStream.read(buffer,0,len))!=-1){
String msg=new String(buffer,0,len);
System.out.println(msg);
}
*/
//管道流
byteArrayOutputStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = inputStream.read(buffer)) != -1) {
byteArrayOutputStream.write(buffer, 0, len);
}
System.out.println(byteArrayOutputStream.toString());
}
} catch (IOException e) {
e.printStackTrace();
}finally {
//关闭资源,倒着关
if (byteArrayOutputStream != null) {
try {
byteArrayOutputStream.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) throws Exception {
//1.创建服务
ServerSocket serverSocket = new ServerSocket(9000);
//2.监听客户端连接
Socket socket = serverSocket.accept();//阻塞式监听,会一直等待客户连接
// Scanner scanner = new Scanner(System.in);
// scanner.next();
//3.获取输入流
InputStream inputStream =socket.getInputStream();
//4.文件输出管道
FileOutputStream fileOutputStream = new FileOutputStream(new File("receive1.png"));
byte[] buffer = new byte[1024];
int len;
while ((len=inputStream.read(buffer))!=-1) {
fileOutputStream.write(buffer,0,len);
}
//通知客户端接受完毕,可以断开
OutputStream outputStream=socket.getOutputStream();
outputStream.write("接收完毕".getBytes());
//关闭资源
fileOutputStream.close();
inputStream.close();
socket.close();
serverSocket.close();
}
}
客户端
public class TcpClientDemo02 {
public static void main(String[] args) throws Exception {
//1.创建一个socaket连接
Socket socket = new Socket(InetAddress.getByName("127.0.0.1"),9000);
//2.创建一个输出流
OutputStream outputStream = socket.getOutputStream();
//3.读取文件流
FileInputStream fileInputStream = new FileInputStream(new File("1.png"));
//4.写出文件
byte[] buffer = new byte[1024];
int len;
while ((len=fileInputStream.read(buffer))!=-1){
outputStream.write(buffer,0,len);
}
//通知服务器,已经结束了
socket.shutdownOutput();//传输完毕
//确认服务器接收完毕,才能断开连接
InputStream inputStream = socket.getInputStream();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
byte[] buffer2 = new byte[2048];
int len2;
while ((len2=inputStream.read(buffer2))!=-1){
byteArrayOutputStream.write(buffer2,0,len2);
}
System.out.println(byteArrayOutputStream.toString());
//5.关闭资源
fileInputStream.close();
outputStream.close();
socket.close();
}
}
Tomcat
服务端
- 自定义
- Tomcat服务器
客户端
- 自定义
- 浏览器
[阿帕奇官网](Apache Tomcat® - 欢迎!)
UDP(发短信)
发短信:
//不需要连接服务器
public class UDPClientDemo01 {
public static void main (String[] args) throws Exception{
//1.建立一个Socket
DatagramSocket datagramSocket = new DatagramSocket();
//2.建个包4
String msg="阿娆真漂亮";
//发给谁
InetAddress localhost =InetAddress.getByName("localhost");
int port = 9000;
//数据,数据的长度其实,要发给谁
DatagramPacket datagramPacket = new DatagramPacket(msg.getBytes(),0,msg.getBytes().length,localhost,port);
//3.发个包
datagramSocket.send(datagramPacket);
//4.关闭流
datagramSocket.close();
}
}
public class UDPServerDemo01 {
public static void main(String[] args) throws Exception {
//开放端口
DatagramSocket datagramSocket = new DatagramSocket(9000);
//接收数据包
byte[] buffer = new byte[1024];
DatagramPacket datagramPacket = new DatagramPacket(buffer, 0, buffer.length);
datagramSocket.receive(datagramPacket);
System.out.println(datagramPacket.getAddress().getHostAddress());
// System.out.println(new String(datagramPacket.getData()),0,datagramPacket.getLength());
//关闭
datagramSocket.close();
}
}
聊天模式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sgtMbdvc-1639882171407)(C:\Users\17730\AppData\Roaming\Typora\typora-user-images\image-20211218220248148.png)]
public class Clience extends JFrame implements ActionListener, Runnable {
Socket clientSocket;
JTextArea jTextReceive = new JTextArea();
JTextField jTextSend = new JTextField();
JButton jbc = new JButton("发送");
JScrollPane jsp = new JScrollPane(jTextReceive);
boolean flag = true; //标记是否结束
Thread connenThread; //用于向服务器端发送信息
DataInputStream cin1;
DataOutputStream cout;
static boolean flagclient = false;
public static void main(String[] args) {
new Clience().clientStart();
}
public synchronized void changeFlag(boolean t) {
flagclient = t;
}
public void clientStart() {
try { //连接服务器端,这里使用本机
this.setTitle("客户端,端口号:8080");
this.setLayout(null);
this.setBounds(20, 00, 300, 300);
jsp.setBounds(20, 20, 220, 100);
jTextSend.setBounds(20, 120, 220, 50);
jbc.setBounds(20, 170, 220, 30);
this.add(jsp);
this.add(jTextSend);
this.add(jbc);
this.setVisible(true);
jbc.addActionListener(this);
clientSocket = new Socket("localhost", 8080);
jTextReceive.setText("连接已经建立完毕!\n");
while (flag) {
try (InputStream is = clientSocket.getInputStream()) {
cin1 = new DataInputStream(clientSocket.getInputStream());
try (OutputStream os = clientSocket.getOutputStream()) {
cout = new DataOutputStream(os);
connenThread = new Thread(this);
connenThread.start(); //启动线程,向服务器端发送信息
String aLine;
while (true) {
aLine = cin1.readUTF();
jTextReceive.append("服务器发来信息:" + aLine + "\n");
if (aLine.equals("bye")) {
flag = false;
connenThread.interrupt();
break;
}
}
cout.close();
}
cin1.close();
}
clientSocket.close(); //关闭Socket连接
System.exit(0);
}
} catch (Exception e) {
System.out.println(e);
}
}
@Override
public void run() {
while (true) {
try {
Thread.sleep(10);
} catch (InterruptedException ex) {
Logger.getLogger(Clience.class.getName()).log(Level.SEVERE, null, ex);
}
try {
if (flagclient == true) {
String str = jTextSend.getText().trim();
if(str==null||str.length()<=0){}
else{
jTextReceive.append("发送消息:" + str + "\n");
cout.writeUTF(str);
cout.flush();}
jTextSend.setText(null);
changeFlag(false);
}
} catch (Exception e) {
System.out.println(e);
}
}
}
@Override
public void actionPerformed(ActionEvent e) {
JButton jbt = (JButton) e.getSource();
if (jbt == jbc) //若单击确认对话框中的“发送”按钮
{
changeFlag(true);
}
}
}
public class Server extends JFrame implements ActionListener, Runnable {
JTextArea jTextReceive = new JTextArea();
JTextField jTextSend = new JTextField();
JButton jbs = new JButton("发送");
ServerSocket server = null;
JScrollPane jsp = new JScrollPane(jTextReceive);
Socket clientSocket; //负责当前线程中C/S通信中的Socket对象
boolean flag = true; //标记是否结束
Thread connenThread; //向客户端发送信息的线程
BufferedReader sin; //输入流对象
DataInputStream sin1;
DataOutputStream sout; //输出流对象
boolean flags = false;
public static void main(String[] args) {
Server MS = new Server();
MS.serverStart();
}
public synchronized void changeFlag(boolean t){
flags=t;
}
public void serverStart() {
try {
server = new ServerSocket(8080); //建立监听服务
this.setTitle("服务器端,端口号:" + server.getLocalPort());
this.setLayout(null);
this.setBounds(20, 00, 300, 300);
jsp.setBounds(20, 20, 220, 100);
jTextSend.setBounds(20, 120, 220, 50);
jbs.setBounds(20, 170, 220, 30);
this.add(jsp);
this.add(jTextSend);
this.add(jbs);
this.setVisible(true);
jbs.addActionListener(this);
while (flag) {
clientSocket = server.accept();
jTextReceive.setText("连接已经建立完毕!\n");
try (InputStream is = clientSocket.getInputStream()) {
sin = new BufferedReader(new InputStreamReader(is));
try (OutputStream os = clientSocket.getOutputStream()) {
sin1 = new DataInputStream(clientSocket.getInputStream());
sout = new DataOutputStream(os);
connenThread = new Thread(this);
connenThread.start(); //启动线程,向客户端发送信息
String aLine;
while(true){
aLine=sin1.readUTF();
jTextReceive.append("客户端发来信息:" +aLine+"\n");
if (aLine.equals("bye")) {
flag = false;
connenThread.interrupt();
break;
}
}
sout.close();
}
sin.close();
}
clientSocket.close(); //关闭Socket连接
System.exit(0); //程序运行结束
}
} catch (Exception e) {
System.out.println(e);
}
}
@Override
public void run() {
while (true) {
try {
Thread.sleep(10);
} catch (InterruptedException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
try {
if (flags == true) {
changeFlag(false);
String str = jTextSend.getText().trim();
if(str==null||str.length()<=0){}
else{
sout.writeUTF(str);
sout.flush();
jTextReceive.append("服务器发送消息:"+str+"\n"); }
jTextSend.setText("");
}
} catch (Exception e) {
System.out.println(e);
}
}
}
@Override
public void finalize() //析构方法
{
try {
server.close();
} //停止ServerSocket服务
catch (IOException e) {
System.out.println(e);
}
}
@Override
public void actionPerformed(ActionEvent e) {
JButton jbt = (JButton) e.getSource();
if (jbt == jbs) //若单击确认对话框中的“发送”按钮
{
changeFlag(true);
}
}
}
URL
统一资源定位符:定位资源的,定位互联网上的某一个资源
DNS域名解析 www.baidu.com 嘻嘻嘻。xxx.x…x…x
由
协议://IP地址:端口/项目名/资源
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Uxcz7M9M-1639882171408)(C:\Users\17730\AppData\Roaming\Typora\typora-user-images\image-20211219100834383.png)]
public class URLdemo01 {
public static void main(String[] args) throws Exception{
URL url=new URL("http://img.desktx.com/d/file/wallpaper/scenery/20170120/df204ebd7a4829933463e2989deb54c6.jpg");
HttpURLConnection urlConnection=(HttpURLConnection) url.openConnection();
InputStream inputStream= urlConnection.getInputStream();
FileOutputStream fileOutputStream =new FileOutputStream("df204ebd7a4829933463e2989deb54c6.jpg");//爬了一张照片
byte[] buffer =new byte[1024];
int len;
while ((len=inputStream.read(buffer))!=-1){
fileOutputStream.write(buffer,0,len);
}
fileOutputStream.close();
inputStream.close();
urlConnection.disconnect();
}
}
id main(String[] args) throws Exception{
URL url=new URL(“http://img.desktx.com/d/file/wallpaper/scenery/20170120/df204ebd7a4829933463e2989deb54c6.jpg”);
HttpURLConnection urlConnection=(HttpURLConnection) url.openConnection();
InputStream inputStream= urlConnection.getInputStream();
FileOutputStream fileOutputStream =new FileOutputStream(“df204ebd7a4829933463e2989deb54c6.jpg”);//爬了一张照片
byte[] buffer =new byte[1024];
int len;
while ((len=inputStream.read(buffer))!=-1){
fileOutputStream.write(buffer,0,len);
}
fileOutputStream.close();
inputStream.close();
urlConnection.disconnect();
}
}