网络编程
1.1概述
地球村:你在西安,给你美国朋友打电话
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YCLeyqdV-1605597315500)(D:\知识点截图\地球村.png)]
计算机网络:
计算机网络是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路(有线或者无线)连接起来,在网络操作系统,网络管理软件)及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统。
网络编程的目的:传播交流信息,数据互换,通信
想要达到这个效果需要什么:
1.如何准确的定位网络上的一台主机 192.168.16.124:端口,定位到这个计算机上的某个资源
2.找到了这个主机,如何传输数据呢?
1.2网络通信的要素
如何实现网络的通信
-
通信双方地址:
- ip
- 端口号
ip+端口号就能定位到某台电脑的某个具体应用
-
规则:网络通信的协议
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A3K0pgE8-1605597315502)(D:\知识点截图\七层协议.png)]
小结:
- 网络编程中有两个主要的问题
- 如何准确的定位到网络上的一台或者多台主机,,百度的主机ip183.232.231.174:,,域名:www.baidu.com
- 找到主机之后如何进行通信
- 网络编程中的要素
- ip和端口号
- 网络通信协议
- 网络编程中有两个主要的问题
1.3IP
ip地址:InetAddress
-
唯一定位一台网络上的计算机
-
127.0.0.1:本机:localhost
-
ip地址的分类:
-
ipv4/ipv6
-
ipv4 127.0.0.1,四个字节组成。0~255,42亿个
-
ipv6 :128位。8个无符号位整数!
例如:2001:aaaa:1542:4651:4565:d1cd:4569:8914
-
-
公网(互联网,就是上面说的42亿)/私网(局域网)
- 192.168.xx.xx,专门给组织内部使用的
- ABCD类地址
-
-
域名:记忆IP问题
- IP:www.jd.com
1.4端口
端口表示计算机上的一个程序进程,在任务管理器中,用pid来表示进程号
-
不用的进程有不同的端口号,用来区分软件的
-
被规定0~65535
-
TCP/UDP:65535*2 tcp:80,udp:80,单个协议下端口号不能冲突
-
端口分类
-
公有端口0~1023
常用的比如:HTTP:80,HTTPS:443,FTP:21,Telent:23
-
程序注册端口1014~49151,分配用户或者程序
- 常用的比如:Tomcat:8080,MySQL:3306,Oracle:1521
-
动态、私有:49152~65535
-
netstat -ano//在cmd中查看所有的端口
netstat -ano|findstr "5900"//查看指定的端口
快速打开任务管理器:ctrl+shift+esc
1.5通信协议
协议:就是约定,就好比我们现在主要就是说普通话
网络通信协议:速率,传输码率,代码结构,传输控制…等等,,,这个非常的复杂
大事化小:分层!
TCP/IP协议簇:实际上是一组协议
重要:
- TCP:用户传输协议,就好比打电话,
- UDP:用户数据报协议,就好比发短信,发完就不管了
出名的:
- TCP
- IP
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XjSVhqPn-1605597315503)(D:\知识点截图\七层协议2.jpg)]
TCP和UDP的对比
TCP:打电话
-
连接,稳定
-
三次握手,四次挥手(可以自己上网查看,更加详细)
最少需要三次,保证稳定连接 A:询问是否在 B:回答在 A:回答在之后,要等待A是否还在,在就连接 A:我要走了 B:你真的要走了吗? B:你真的真的要走了吗? A:我真的要走了
-
客户端,服务端
-
传输完成,释放链接,效率低
UDP:发短信
- 不连接,不稳定
- 客户端,服务端:没有明确的界限
- 不管有没有准备好,都可以发给你
- 导弹,不需要对面同意
1.6TCP
有序列表的使用:1.+空格
客户端
- 连接服务器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 = 40000;
//2.创建一个socket连接
socket = new Socket(serverIp,port);
//3.发送消息,使用到io流
os = socket.getOutputStream();
String str = "你真的垃圾";
os.write(str.getBytes());
} catch (IOException 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 ss = null;
Socket socket = null;
InputStream is = null;
ByteArrayOutputStream bas = null;
try {
//1.首先我要有一个地址(端口号)创建一个serversocket连接
ss = new ServerSocket(40000);
//2.等待客户端连接
socket = ss.accept();
//3.读取客户端的消息
is = socket.getInputStream();
//管道流
bas = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len=is.read(buffer)) != -1){
bas.write(buffer,0,len);
}
System.out.println(bas.toString());
} catch (IOException e) {
e.printStackTrace();
} finally {
//4.关闭流
if (bas != null) {
try {
bas.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 (ss != null) {
try {
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
TCP文件上传实现
客户端
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
public class TcpClientDemo02 {
public static void main(String[] args) {
Socket socket = null;
OutputStream os = null;
FileInputStream fis = null;
InputStream is2 = null;
ByteArrayOutputStream baos2 = null;
try {
//1.创建一个Socket连接
socket = new Socket(InetAddress.getByName("127.0.0.1"),9000);
//2.创建一个输出流
os = socket.getOutputStream();
//3.读取文件
fis = new FileInputStream(new File("鄙视链.png"));
//4.写出文件
byte[] buffer = new byte[1024];
int len;
while ((len = fis.read(buffer)) != -1){
os.write(buffer,0,len);
}
//通知服务器,我已经发送完了
socket.shutdownOutput();
//确定服务器接受完毕,才可以断开连接
is2 = socket.getInputStream();
baos2 = new ByteArrayOutputStream();
byte[] buffer2 = new byte[1024];
int len2;
while ((len2 = is2.read(buffer2)) != -1){
baos2.write(buffer2,0,len2);
}
System.out.println(baos2.toString());
} catch (IOException e) {
e.printStackTrace();
} finally {
//5.关闭资源
if (baos2 != null) {
try {
baos2.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (is2 != null) {
try {
is2.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();
}
}
}
}
}
服务端
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class TcpServerDemo02 {
public static void main(String[] args) {
ServerSocket ss = null;
Socket socket = null;//阻塞式监听,会一直等待客户端连接
InputStream is = null;
FileOutputStream fos = null;
OutputStream os3 = null;
try {
//1.创建端口号
ss = new ServerSocket(9000);
//等待客户端链接
socket = ss.accept();
//获取输入流
is = socket.getInputStream();
//4.文件输出
fos = new FileOutputStream(new File("receive.png"));
byte[] buffer = new byte[1024];
int len;
while ((len = is.read(buffer)) != -1){
fos.write(buffer,0,len);
}
//通知客户端我接受完毕了
os3 = socket.getOutputStream();
os3.write("我接收完毕了,你可以断开了".getBytes());
} catch (IOException e) {
e.printStackTrace();
} finally {
//关闭资源
if (os3 != null) {
try {
os3.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos != null) {
try {
fos.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 (ss != null) {
try {
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
Tomcat
服务端
- 自定义:S
- Tomcat服务器:S
客户端
- 自定义:C
- 浏览器:B
1.7UDP
发短信:不用连接,需要知道对方的地址!
发送消息
发送端
//不需要连接服务器
public class UdpClientDemo01 {
public static void main(String[] args) {
DatagramSocket ds = null;
try {
//1.建立一个Socket
ds = new DatagramSocket();
//2.建立一个包
InetAddress localhost = InetAddress.getByName("localhost");
int port = 9090;
String str = "你好啊,服务器!";
DatagramPacket dgp = new DatagramPacket(str.getBytes(),0,str.getBytes().length,localhost,port);
//3.发送包
ds.send(dgp);
} catch (IOException e) {
e.printStackTrace();
} finally {
//关闭流
if (ds != null) {
ds.close();
}
}
}
}
接收端
public class UdpServerDemo01 {
public static void main(String[] args) {
DatagramSocket dgs = null;
try {
//开放端口
dgs = new DatagramSocket(9090);
//接受数据包
byte[] buffer = new byte[1024];
DatagramPacket dgp = new DatagramPacket(buffer,0,buffer.length);//接受
dgs.receive(dgp);//阻塞接受
System.out.println(dgp.getAddress().getHostAddress());
System.out.println(new String(dgp.getData(),0,dgp.getLength()));
} catch (IOException e) {
e.printStackTrace();
} finally {
//关闭连接
if (dgs != null) {
dgs.close();
}
}
}
}
1.8URL
统一资源定位符:定位资源的,定位互联网上的某个资源
https://www.baidu,com/
格式:协议://ip地址:端口/项目名/资源
public class UrlDown {
public static void main(String[] args) {
HttpURLConnection urlConnection = null;
InputStream inputStream = null;
FileOutputStream fos = null;
try {
//1.下载地址
URL url = new URL("网上真实的地址");//比如http://localhost:8080/qingjiang/SecurityFile.txt
//2.连接到这个资源 ,需要协议
urlConnection = (HttpURLConnection)url.openConnection();
inputStream = urlConnection.getInputStream();
fos = new FileOutputStream("保存的名字");
byte[] buffer = new byte[1024];
int len;
while ((len = inputStream.read(buffer)) != -1) {
fos.write(buffer,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (urlConnection != null) {
urlConnection.disconnect();
}
}