目录
一、网络分层
1、OSI七层
应用层: HTTP FTP POP3 SMTP TELNET ...
表示层:
会话层:
传输层: TCP UDP
网络层: IP
数据链路层
物理层
2、TCP/IP协议
应用层 --- 应用层,表示层,会话层
传输层 --- 传输层
网际层 --- 网络层
网络层 --- 数据链路层,物理层
二、计算机网络的基本要素
1、IP地址(门牌号)
计算在网络中的唯一标识
ipv4 - 32位
127.0.0.1 -- 指向当前机器
255.255.255.255 -- 广播地址
ipv6 - 128位
2、主机名
因为ip地址难于记忆,可以为不同的主机起不同的名字 来唯一标识 这个唯一标识主机的名字 称为主机名 和 ip地址具有映射关系
127.0.0.1 localhost 代表本机
3、域名
全网认可的主机名 域名不能随意用 需要注册 先到先得 收取一定费用
4、域名解析
DNS服务器:域名解析服务器 接受域名 解析为 ip 返回
5、Hosts文件
windows自带的机制 可以在本地做主机名 和ip 的映射
在windows中使用主机名时 会先查找hosts文件 得到主机名和ip的映射 得到就用 得不到再求访问公网上的dns服务器翻译
C:\Windows\System32\drivers\etc\hosts
6、端口
每个计算机都有 若干个 可以供外界连接的窗口 每个窗口都有独一无二的编号 程序可以监听指定的端口号
外界通过ip连接到当前机器后 将数据发送 给指定端口号 从而 让正在监听该端口的程序收到数据。
范围:0~65535 其中0~1024是被系统占用了的,我们不能使用。
7、协议
网络中主机之间通信的规范
HTTP :80
HTTPS :443
SMTP :25
SSH :22
三、InetAddress
java.net.InetAddress - 此类表示互联网协议 (IP) 地址
主要方法:
static InetAddress getLocalHost() //获取本机ip地址对象
static InetAddress getByName(String host) //根据给定ip或主机名 获取ip地址对象
String getHostName() //获取当前对象代表的主机的主机名
String getHostAddress() //获取当前对象代表的主机的ip地址
四、传输协议
1、UDP
不需要建立连接
将数据及源和目的地封装为数据包
每个数据报的大小限制在64k内
因为无连接,是不可靠协议
优点:快
缺点:会丢数据
应用场景:数据及时传输要求高,但是数据稳定性不需保证的场景(例如:QQ,微信聊天)
2、TCP
建立连接,形成传输数据的通道
在连接中进行大数据量传输,靠流来进行操作
三次握手,是可靠协议
必须先建立连接,效率会稍低
优点:不丢数据
缺点:效率相对较低
应用场景: 要求可靠性比较高的场景(web服务)
五、java中的socket编程
1、利用socket实现UDP通信
java.net.DatagramSocket - UDP协议的编程接口类,负责收发数据包
构造方法:
DatagramSocket()//通常用来发送
DatagramSocket(int port)//通常用来接收
相关方法:
void send(DatagramPacket p) //发送数据包
void receive(DatagramPacket p) //接收数据包
void close() //关闭套接字
数据包:
java.net.DatagramPacket - UDP的数据包,内含 数据 数据来源 数据目的地
构造:
DatagramPacket(byte[] buf, int length)//一般用做接收
DatagramPacket(byte[] buf, int length, InetAddress address, int port) //一般用作发送
相关方法:
InetAddress getAddress()
int getLength()
byte[] getData()
int getPort()
案例代码:利用UDP实现客户端和服务器通信
UDPServer:
java
/**
* java利用socket实现基于UDP协议的服务端
*/
public class UDPServer {
public static void main(String[] args) throws Exception {
//构建UDP服务端并监听服务端口--8000
DatagramSocket udpSocket = new DatagramSocket(8000);
//构建接收数据包的对象
byte[] bytes = new byte[1024];
DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length);
//接收数据包
System.err.println("数据等待中,请稍后...");
udpSocket.receive(datagramPacket);
//获取接收的数据
byte[] reciveData = datagramPacket.getData();
//打印获取的内容
String result = new String(reciveData, 0, reciveData.length, "utf-8");
System.out.println("客户端发送的信息:"+result);
//关闭资源
udpSocket.close();
}
}
UDPClient:
java
/**
* java利用socket实现基于UDP协议的客户端
*/
public class UDPClient {
public static void main(String[] args) throws Exception {
//构建UDP客户端
DatagramSocket datagramSocket = new DatagramSocket();
//扫描器接收用户输入
Scanner scanner = new Scanner(System.in);
System.out.println("客户端准备发送数据:");
byte[] content = scanner.next().getBytes("utf-8");
//构建服务器的地址对象
InetAddress localhost = InetAddress.getByName("127.0.0.1");
//封装数据包
DatagramPacket datagramPacket = new DatagramPacket(content, content.length, localhost, 8000);
//发送数据
datagramSocket.send(datagramPacket);
System.out.println("数据发送完成...");
//关闭资源
datagramSocket.close();
}
}
2、利用socket实现TCP通信
1)主要流程
需要经历三次握手建立连接
用流来传输大量数据
有数据包重发机制 实现可靠的数据传输
可以双向传输数据
TCP基于连接工作 连接具有两端 称为服务器端 和 客户端
把主动发起请求的一端 称为客户端 被动等待请求 接收连接的一方称之为 服务器端
2)java中的主要api
--代表soket地址的类:
SocketAddress - InetSocketAddress
构造方法:
InetSocketAddress(InetAddress addr, int port)
InetSocketAddress(String hostname, int port)
其他方法:
InetAddress getAddress()
String getHostName()
int getPort()
--表示TCP socket客户端的类:
java.net.Socket
构造方法:
Socket()
Socket(InetAddress address, int port)
Socket(String host, int port)
相关方法:
void connect(SocketAddress endpoint) //开始连接服务器
void connect(SocketAddress endpoint, int timeout) //开始连接服务器,额外指定超时时间
InetAddress getInetAddress() //获取连接的地址
int getPort() //获取连接的端口
InputStream getInputStream() //获取输入流
OutputStream getOutputStream() //获取输出流
void shutdownInput() //结束对输入流的读取,不会关闭流,只是无法再从流中读取数据
void shutdownOutput() //结束对输出流的输入,不会关闭流,只是无法再向流中写出数据
boolean isInputShutdown() //判断输入流是否已经被置于结束状态
boolean isOutputShutdown() //判断输出流是否已经被置于结束状态
void close() //关闭套接字 自动关闭底层输入输出流
--表示TCP socket服务端的类:
java.net.ServerSocket
构造方法:
ServerSocket()
ServerSocket(int port)
相关方法:
Socket accept() //开始接受连接 一旦调用 就进入阻塞状态 直到有一个客户端连接过来 才会解除阻塞继续运行
void close() //关闭套接字 自动关闭底层输入输出流
InetAddress getInetAddress() //获取地址对象
int getLocalPort() //获取本地监听端口
java基于socket通信的TCP案例:
服务端:
java
/**
* Server socket Tcp
*/
public class ServerSocketForTCP {
public static void main(String[] args) throws Exception {
//1、构建server socket对象(监听端口)
ServerSocket serverSocket = new ServerSocket(9999);
//2、等待客户端链接Socket(套接字)
Socket accept = serverSocket.accept();
//3、基于socket获取输入流接收客户端的数据
InputStream inputStream = accept.getInputStream();
//4、流处理
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String msg = bufferedReader.readLine();
System.out.println("Server端接收到的消息:"+msg);
//5、关闭资源
serverSocket.close();
}
}
客户端:
java
/**
* Client socket Tcp
*/
public class ClientSocketForTCP {
public static void main(String[] args) throws Exception {
//1、构建客户端的socket
Socket socket = new Socket();
//2、连接到服务端
//构建socker地址对象
InetSocketAddress socketAddress = new InetSocketAddress("localhost", 9999);
socket.connect(socketAddress);
//3、基于socker完成数据传递
OutputStream outputStream = socket.getOutputStream();
PrintStream printStream = new PrintStream(outputStream);
printStream.print("你好,我是客户端信息");
//4、关闭资源
socket.close();
}
}