@nextleaf
2018-08-24T11:56:20.000000Z
字数 5385
阅读 1338
Java
工作日志
网络
IP
TCP
线程同步
线程生命周期
线程间通信
线程死锁
网络编程
五层协议只是OSI和TCP/IP的综合,是业界产生出来的非官方协议模型,实际应用还是TCP/IP的四层结构
OSI七层网络模型 |
TCP/IP四层概念模型 |
对应网络协议 |
应用层(Application) |
应用层 |
HTTP、TFTP, FTP, NFS, WAIS、SMTP |
表示层(Presentation) |
应用层 |
Telnet, Rlogin, SNMP, Gopher |
会话层(Session) |
应用层 |
SMTP, DNS |
传输层(Transport) |
传输层 |
TCP, UDP |
网络层(Network) |
网络层 |
IP, ICMP, ARP, RARP, AKP, UUCP |
数据链路层(Data Link) |
数据链路层(网络接口层) |
FDDI, Ethernet, Arpanet, PDN, SLIP, PPP |
物理层(Physical) |
数据链路层(网络接口层) |
IEEE 802.1A, IEEE 802.2到IEEE 802.11 |
OSI七层和TCP/IP四层的关系
- OSI引入了服务、接口、协议、分层的概念,TCP/IP借鉴了OSI的这些概念建立TCP/IP模型。
- OSI先有模型,后有协议,先有标准,后进行实践;而TCP/IP则相反,先有协议和应用再提出了模型,且是参照的OSI模型。
- OSI是一种理论下的模型,而TCP/IP已被广泛使用,成为网络互联事实上的标准。
TCP:transmission control protocol 传输控制协议
UDP:user data protocol 用户数据报协议
OSI是Open System Interconnect的缩写,意为开放式系统互联。
OSI七层参考模型的各个层次的划分遵循下列原则:
1)根据不同层次的抽象分层
2)每层应当有一个定义明确的功能
3)每层功能的选择应该有助于制定网络协议的国际标准。
4)各层边界的选择应尽量节省跨过接口的通信量。
5)层数应足够多,以避免不同的功能混杂在同一层中,但也不能太多,否则体系结构会过于庞大
6)同一层中的各网络节点都有相同的层次结构,具有同样的功能。
7)同一节点内相邻层之间通过接口(可以是逻辑接口)进行通信。
8)七层结构中的每一层使用下一层提供的服务,并且向其上层提供服务。
9)不同节点的同等层按照协议实现对等层之间的通信。
层次特征:
物理层的主要功能是:利用传输介质为数据链路层提供物理连接,实现比特流的透明传输。
数据链路层的主要功能是:通过各种控制协议【介质访问控制(MAC)和逻辑链路控制(LLC)】,将有差错的物理信道变为无差错的、能可靠传输数据帧的数据链路。
网络层主要任务是:通过路由选择算法,为报文或分组通过通信子网选择最适当的路径。
寻址、交换、路由算法、连接服务
传输层的主要任务是:向用户提供可靠的端到端的差错和流量控制,保证报文的正确传输。
传输连接管理、处理传输差错、监控服务质量
会话层,会话管理、会话流量控制、寻址、出错控制。
表示层的主要功能是“处理用户信息的表示问题,如编码、数据格式转换和加密解密”等。
数据格式处理、数据的编码、压缩和解压缩、数据的加密和解密
应用层功能是直接向用户提供服务,完成用户希望在网络上完成的各种工作。
提供用户接口、实现各种服务
1)第七至第四层(应用层->表示层->会话层->传输层)处理数据源和数据目的地之间的端到端通信,
2)第三至第一层(网络层->数据链路层->物理层)处理网络设备间的通信。
1)TCP/IP协议中的应用层处理OSI模型中的第五层、第六层和第七层的功能。
2)TCP/IP协议中的传输层并不能总是保证在传输层可靠地传输数据包,而OSI模型可以做到。
3) TCP/IP协议还提供一项名为UDP(用户数据报协议)的选择。UDP不能保证可靠的数据包传输。
开放系统互连参考模型
端口号和IP地址组合得出一个网络套接字。
不同的进程有不同的端口号。
TCP 三次握手和四次挥手
package com.nl.sx823.networkprogram;
/**
* Created with IntelliJ IDEA 2018.
* Description:这个类表示互联网协议(IP)地址
* 方法:
* 1 static InetAddress getByAddress(byte[] addr) 在给定原始 IP 地址的情况下,返回 InetAddress 对象。
* 2 static InetAddress getByAddress(String host, byte[] addr) 根据提供的主机名和 IP 地址创建 InetAddress。
* 3 static InetAddress getByName(String host) 在给定主机名的情况下确定主机的 IP 地址。
* 4 String getHostAddress() 返回 IP 地址字符串(以文本表现形式)。
* 5 String getHostName() 获取此 IP 地址的主机名。
* 6 static InetAddress getLocalHost() 返回本地主机。
* 7 String toString() 将此 IP 地址转换为 String。
*
* @author: 黄昭鸿
* @date: 2018-08-23
* Time: 17:53
*/
import java.net.InetAddress;
public class InetAddressDemo {
public static void main(String[] args) throws Exception {
//获取本机的IP
InetAddress inet=InetAddress.getLocalHost();
System.out.println(inet);
//获取主机名称
System.out.println(inet.getHostName());
//获取当前主机IP
System.out.println(inet.getHostAddress());
InetAddress inet1=InetAddress.getByName("fanyi.baidu.com");
System.out.println(inet1.getHostName());
System.out.println(inet1.getHostAddress());
}
}
服务器端
package com.nl.sx823.networkprogram.socket;
import cn.hutool.core.util.NetUtil;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
/**
* Created with IntelliJ IDEA 2018.
* Description:Socket服务器
* java.net.Socket 类代表客户端和服务器都用来互相沟通的套接字。客户端要获取一个 Socket 对象通过实例化 ,而 服务器获得一个 Socket 对象则通过 accept() 方法的返回值。
*
* @author: 黄昭鸿
* @date: 2018-08-24
* Time: 10:30
*/
public class GreetingServer extends Thread {
private ServerSocket serverSocket;
@Override
public void run() {
while (true) {
try {
System.out.println("等待远程连接,端口号为:" + serverSocket.getLocalPort() + "...");
System.out.println();
Socket server = serverSocket.accept();
System.out.println("远程客户端地址:" + server.getRemoteSocketAddress());
DataInputStream in = new DataInputStream(server.getInputStream());
System.out.println("收到客户端信息:" + in.readUTF());
DataOutputStream out = new DataOutputStream(server.getOutputStream());
out.writeUTF("蟹蟹连接我:" + server.getLocalSocketAddress() + ",ヾ( ̄▽ ̄)Bye~Bye~!");
System.out.println();
in.close();
out.close();
server.close();
} catch (SocketTimeoutException s) {
System.out.println("Socket timed out!");
break;
} catch (IOException e) {
e.printStackTrace();
break;
}
}
}
private GreetingServer(int port) throws IOException {
serverSocket = new ServerSocket(port);
//通过指定超时值启用/禁用 SO_TIMEOUT,以毫秒为单位。
serverSocket.setSoTimeout(3600000);
}
public static void main(String[] args) {
//int port = Integer.parseInt(args[0]);
try {
//检测本地端口可用性
if (NetUtil.isUsableLocalPort(9090)) {
//Thread t = new GreetingServer(port);
Thread t = new GreetingServer(9090);
t.run();
}else {
System.out.println("端口已被占用");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
客户端
package com.nl.sx823.networkprogram.socket;
import java.io.*;
import java.net.Socket;
/**
* Created with IntelliJ IDEA 2018.
* Description:Socket客户端
* java.net.Socket 类代表客户端和服务器都用来互相沟通的套接字。客户端要获取一个 Socket 对象通过实例化 ,而 服务器获得一个 Socket 对象则通过 accept() 方法的返回值。
* 不同的进程有不同的端口号
* @author: 黄昭鸿
* @date: 2018-08-24
* Time: 10:28
*/
public class GreetingClient {
public static void main(String[] args) {
//String serverName = args[0];
String serverName = "localhost";
//int port = Integer.parseInt(args[1]);
int port = Integer.parseInt("9090");
try {
System.out.println("连接到远程主机:" + serverName + " ,端口号:" + port);
Socket client = new Socket(serverName, port);
System.out.println("远程主机地址:" + client.getRemoteSocketAddress());
OutputStream outToServer = client.getOutputStream();
DataOutputStream out = new DataOutputStream(outToServer);
out.writeUTF("我是客户端的消息(客户端地址: " + client.getLocalSocketAddress()+")");
InputStream inFromServer = client.getInputStream();
DataInputStream in = new DataInputStream(inFromServer);
System.out.println();
System.out.println("服务器响应: " + in.readUTF());
outToServer.close();
out.close();
inFromServer.close();
in.close();
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}