网络编程
网络编程目的:
无线电台,传播交流信息,数据交换,通信
**前提 **
1.如何准确定位到一台主机: IP + 端口 ,定位到计算机上某个资源
2.找到这个主机,如何传输数据?
IP地址
一个IP地址用于唯一标识一个网络接口,
IP地址分为公网IP地址和内网IP地址。
公网IP地址可以直接被访问,内网IP地址只能被内网访问。
本机地址:127.0.0.1
两台计算机在同一个网络就可以直接通信,因为IP地址前段是相同的,也就是网络号相同的。
网络号是IP地址通过子网掩码过滤后得到的。
如果两台计算机不在同一个网络,他们之间必须通过路由器或交换机这样网络设备间接通信,这种设备称为网关。
网关作用就是连接多个网络,负责把来自一个网络的数据包发到另一个网络,这个过程叫路由
网卡的关键配置:
- IP地址
- 子网掩码
- 网关IP地址
域名
因为直接记忆IP地址非常困难,所以我们通常使用域名访问某个特殊服务。域名解析服务器DNS,负责把域名翻译成对应IP,客户端再根据IP地址访问服务器。
用nslookup 命令可以查看域名对应IP地址。
网络模型
分层模型:
| OSI | TCP/IP |
|---|---|
| 应用层 | |
| 表示层 | 应用层 |
| 会话层 | |
| 传输层 | 传输层 |
| 网络层 | 网络层 |
| 链路层 | 网络接口层 |
| 物理层 |
学习时是按照五层协议模型学习
| 应用层 | HTTP,FTP,DNS.SMTP |
|---|---|
| 传输层 | TCP,UDP |
| 网络层 | IP,ICMP,ARP,RARP,AKP,UUCP |
| 数据链路层 | FDDI,Ethernet,Arpanet,PDN,SLIP,PPP |
| 物理层 | IEEE 802.1A |
小结:
1.网络编程两个主要问题
- 如何准确定位网络上一台或多台主机
- 找到主机之后如何通信
2.网络编程中要素
- IP 和 端口号
- 网络通信协议
3.万物皆对象
IP
IP地址:InetAddress类
- 唯一定位一台网络上计算机
- 127.0.0.1:本机localhost
- IP地址分类
- IP地址分类
- IPV4,四个字节组成 0-255
- IPV6,128位,8个无符号整数
- 公网(互联网)和私网(局域网)分类
- IP地址分类
- 域名:记忆IP问题
**常用方法 **
- .getAddress() 获得IP地址
- .getCanonicalHostName(),获得IP地址完全限定域名,规范名字
- .getHostAddress(),获得IP地址的字符串形式
- .getHostName(),获取此IP地址的主机名
端口
端口表示计算机上一个程序的进程;InetSocketAddress类
- 不同的进程有不同端口号,用来区分软件
- 被规定0-65535
- TCP UDP:单个协议,端口号不能冲突
- 端口分类:
- 公有端口:0-1023
- HTTP:80
- HTTPS:443
- FTP:21
- Telent:23
- 程序注册端口:1024-49151 分配用户或程序
- Tomcat:8080
- MySQL:3306
- Oracle:1521
- 动态私有:49512-65535
- 公有端口:0-1023
netstat -ano #查看所有端口
netstat -ano|findstr "5900"#查看指定端口
tacklist|findstr "8696" #查看指定端口进程
通信协议
网络通信协议:速率、传输码率、代码结构、传输控制
分层!
TCP/IP协议簇
- TCP:用户传输协议
- UDP:用户数据报协议
- IP:网络互联协议
TCP和UDP对比
TCP:类似于打电话
- 连接、稳定
- 三次握手、四次挥手
- 客户端、服务端
- 传输完成,释放连接,效率低
UDP:类似于发短信
- 不连接,不稳定
- 客户端,服务端没有明确界限
- 不管有没有准备好,都可以发送
- DDOS:饱和攻击
TCP
客户端
1.得到服务器地址和端口,InetAddress类 获得IP地址,int类获得端口
2.连接服务器,创建个Socket 实例,参入参数时IP地址和端口号
3.发送消息,通过socket的.getOutputStream()方法创建输出流
通过.write()方法发送消息
服务器
1.建立服务的端口,创建ServerSocket实例,传入参数为端口号
2.等待用户连接,使用ServerSocket实例.accpet()方法创建个socket()接收器监听
3.接收用的消息,通过socket().getInputStream()获取消息
4.通过管道流,对消息处理进行输出。
最后一定要释放资源,从后往前逐个释放
文件上传
package XiaoShuai;
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
//客户端
public class TcpClientDemo {
public static void main(String[] args) throws Exception {
//1.创建一个Socket连接
Socket socket = new Socket(InetAddress.getByName("127.0.0.1"),9999);
//2.创建一个输出流
OutputStream os = socket.getOutputStream();
//3.文件流
FileInputStream fis = new FileInputStream("xiaoshuai.png");
//4.写入文件
byte[] buffer = new byte[1024];
int len;
while((len = fis.read(buffer)) != -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);
//5.关闭资源
baos.close();
is.close();
fis.close();
os.close();
socket.close();
}
}
/*
* 第三步,使用Socket类,建立Socket连接,
* 第四步,创建一个输出流,os
* 第五步,创建一个文件流,fis 接收文件
* 第六步,写入文件,将文件流写入输出流
* 第七步,通知服务器,传输完毕
*
* 第十一步,确定服务器接收完毕,断开baos
* 第十二步,关闭资源
* */
接收文件
package XiaoShuai;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
//服务端
public class TcpServerDemo {
public static void main(String[] args) throws Exception {
//1.创建服务
ServerSocket serverSocket = new ServerSocket(9999);
//2.监听客户端连接
Socket socket = serverSocket.accept();
//3.获取输入流
InputStream is = socket.getInputStream();
//4.文件输出
FileOutputStream fos = new FileOutputStream("xiaomei.png");
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(StandardCharsets.UTF_8));
//关闭资源
os.close();
fos.close();
is.close();
socket.close();
serverSocket.close();
}
}
/*
* 第一步,创建一个服务连接接口,serverSocket 传入参数为端口号
* 第二步,监听客户端连接,监听客户端的文件流传入
*
* 第八步,获取输入流,使用is
* 第九步,对输入的流进行输出。fos
* 第十步,通知客户端接收完毕
* */
UDP
1.无连接,不稳定
发送端
package XiaoShuai;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.nio.charset.StandardCharsets;
//UDP,不需要连接服务器
public class UDPClientDemo {
public static void main(String[] args) throws Exception {
//1.建立一个Socket类
DatagramSocket socket = new DatagramSocket();
//2.建立一个包
String msg = "大学生小帅";
InetAddress localhost = InetAddress.getByName("localhost");
int port = 8888;
DatagramPacket packet = new DatagramPacket(msg.getBytes(StandardCharsets.UTF_8),0,msg.getBytes().length,localhost,port);
//3.发送包
socket.send(packet);
//4.关闭流
socket.close();
}
}
/*
4.建立一个socket类,创建连接端口(进入一个快递站)
5.建立一个包,确定发送内容,确定发送地址和端口,写入包(寄出包裹,确定包裹内容,大小,目的地)
6.发送包send(),发送包裹
7.关闭流,离开快递站
*/
接收端
package XiaoShuai;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.nio.charset.StandardCharsets;
//UDP,不需要连接服务器
public class UDPClientDemo {
public static void main(String[] args) throws Exception {
//1.建立一个Socket类
DatagramSocket socket = new DatagramSocket();
//2.建立一个包
String msg = "大学生小帅";
InetAddress localhost = InetAddress.getByName("localhost");
int port = 8888;
DatagramPacket packet = new DatagramPacket(msg.getBytes(StandardCharsets.UTF_8),0,msg.getBytes().length,localhost,port);
//3.发送包
socket.send(packet);
//4.关闭流
socket.close();
}
}
/*
4.建立一个socket类,创建连接端口(进入一个快递站)
5.建立一个包,确定发送内容,确定发送地址和端口,写入包(寄出包裹,确定包裹内容,大小,目的地)
6.发送包send(),发送包裹
7.关闭流,离开快递站
*/
浙公网安备 33010602011771号