什么是网络?java
在计算机领域中,网络是信息传输、接受、共享的虚拟平台。编程
经过它把各个点、面、体的信息联系到一块儿,从而实现这些资源的共享。数组
什么是网络编程?服务器
网络编程从大的方面就是说对信息的发送接收。网络
经过操做相应API调度计算机资源硬件,而且利用管道(网线)进行数据交互的过程。并发
更为具体的涉及:网络模型、套接字、数据包。异步
互联网的本质就是一系列的网络协议,这个协议就叫OSI协议(一系列协议),按照功能不一样,分工不一样,人为的分层七层。实际上这个七层是不存在的。没有这七层的概念,只是人为的划分而已。区分出来的目的只是让咱们明白哪一层是干什么用的。socket
每一层都运行不一样的协议。ide
实际上也能够把它划成五层、四层。this
七层划分为:应用层、表示层、会话层、传输层、网络层、数据链路层、物理层。
五层划分为:应用层、传输层、网络层、数据链路层、物理层。
四层划分为:应用层、传输层、网络层、网络接口层。
用户使用的都是应用程序,均工做于应用层,你们均可以开发本身的应用程序,数据多种多样,必须规定好数据的组织形式 。
应用层功能:规定应用程序的数据格式。
好比TCP协议能够为各类各样的程序传递数据,好比Email、WWW、FTP等。那么,必须有不一样协议规定电子邮件、网页、FTP数据的格式,这些应用程序协议就构成了”应用层”。
表示层的用途是提供一个可供应用层选择的服务的集合,使得应用层能够根据这些服务功能解释数据的含义。表示层如下各层只关心如何可靠地传输数据,而表示层关心的是所传输数据的表现方式、它的语法和语义。表示服务的例子有统一的数据编码、数据压缩格式和加密技术等。
会话层任务是:向两个实体的表示层提供创建和使用链接的方法。将不一样实体之间的表示层的链接称为会话。所以会话层的任务就是组织和协调两个会话进程之间的通讯,并对数据交换进行管理。
传输层是通讯子网和资源子网的接口和桥梁,起到承上启下的做用。
该层的主要任务是:向用户提供可靠的端到端的差错和流量控制,保证报文的正确传输。传输层的做用是向高层屏蔽下层数据通讯的细节,即向用户透明地传送报文。
该层常见的协议:TCP/IP中的TCP协议、Novell网络中的SPX协议和微软的NetBIOS/NetBEUI协议。
传输层提供会话层和网络层之间的传输服务,这种服务从会话层得到数据,并在必要时,对数据进行分割。而后,传输层将数据传递到网络层,并确保数据能正确无误地传送到网络层。所以,传输层负责提供两节点之间数据的可靠传送,当两节点的联系肯定以后,传输层则负责监督工做。综上,传输层的主要功能以下:
传输链接管理:提供创建、维护和拆除传输链接的功能。传输层在网络层的基础上为高层提供面向链接和面向无链接的两种服务。
网络层的做用是在网络与网络相互链接的环境中,将数据从发送端主机发送到接受端主机。
举例:
我在学校教室中,我想找隔壁班的妹子,我通知小弟去告诉她,说有个帅哥找你。而小弟就是网关,IP地址就是我所处的教室,MAC地址就是我在教室的某个位置。
早期的时候,数据链路层就是来对电信号来作分组的。之前每一个公司都有本身的分组方式,很是的乱,后来造成了统一的标准,即以太网协议Ethernet。
通讯传输其实是经过物理的传输介质实现的。数据链路层的做用就是在这些同构传输介质互连的设备之间进行数据处理。
物理层中,将数据的 0 、1转换为电压和脉冲光传输给物理的传输介质,而相互直连的设备之间使用地址实现传输。这种地址被称为 MAC 地址,也可称为物理地址或硬件地址。采用 MAC 地址信息的首部附加到从网络层转发过来的数据上,将其发送到网络。
网络层与数据链路层都是基于目标地址将数据发送给接收端的,可是网络层负责将整个数据发送给最终目标地址。而数据链路层则只负责发送一个分段内的数据。
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 |
服务器端先初始化Socket,而后与端口绑定(bind),对端口进行监听(listen),调用accept开始阻塞,等待客户端链接。在这时若是有个客户端初始化一个Socket,而后链接服务器(connect),若是链接成功,这时客户端与服务器端的链接就创建了。客户端发送数据请求,服务器端接收请求并处理请求,而后把回应数据发送给客户端,客户端读取数据,最后关闭链接,一次交互结束。
经过三次握手创建链接,通信完成时要拆除链接
第一次握手
:客户端发送带有 SYN 标志的链接请求报文段,而后进入 SYN_SEND 状态,等待服务端确认。第二次握手
:服务端接受到客户端的 SYN 报文段后,须要发送 ACK 信息对这个 SYN 报文段进行确认。同时,还要发送本身的 SYN 请求信息。服务端会将上述信息放到一个报文段(SYN+ACK 报文段)中,一并发送给客户端,此时服务端进入 SYN_RECV 状态。第三次握手
:客户端接收到服务端的 SYN+ACK 报文段后,会向服务端发送 ACK 确认报文段,这个报文段发送完毕后,客户端和服务端都进入 ESTABLEISHED 状态,完成 TCP 三次握手。面向链接
的因此只能用于端到端的通信。面向无链接
的通信协议。HTTP
、FTP
、SMTP
客户端代码:
/** * @author Jack */ public class Client { public static void main(String[] args) throws IOException { Socket socket = new Socket(); // 超时时间 socket.setSoTimeout(3000); // 链接本地,端口2000;超时时间3000ms socket.connect(new InetSocketAddress(Inet4Address.getLocalHost(), 2000), 3000); System.out.println("已发起服务器链接..."); System.out.println("客户端信息:" + socket.getLocalAddress() + " P:" + socket.getLocalPort()); System.out.println("服务器信息:" + socket.getInetAddress() + " P:" + socket.getPort()); try { // 发送接收数据 todo(socket); } catch (Exception e) { System.out.println("异常关闭"); } // 释放资源 socket.close(); System.out.println("客户端已退出~"); } private static void todo(Socket client) throws IOException { // 构建键盘输入流 InputStream in = System.in; BufferedReader input = new BufferedReader(new InputStreamReader(in)); // 获得Socket输出流,并转换为打印流 OutputStream outputStream = client.getOutputStream(); PrintStream socketPrintStream = new PrintStream(outputStream); // 获得Socket输入流,并转换为BufferedReader InputStream inputStream = client.getInputStream(); BufferedReader socketBufferedReader = new BufferedReader(new InputStreamReader(inputStream)); boolean flag = true; do { // 键盘读取一行 String str = input.readLine(); // 发送到服务器 socketPrintStream.println(str); // 从服务器读取一行 String echo = socketBufferedReader.readLine(); if ("bye".equalsIgnoreCase(echo)) { flag = false; } else { System.out.println(echo); } } while (flag); // 资源释放 socketPrintStream.close(); socketBufferedReader.close(); } }
服务端代码:
/** * @author jack */ public class Server { public static void main(String[] args) throws IOException { ServerSocket server = new ServerSocket(2000); System.out.println("服务器准备就绪..."); System.out.println("服务器信息:" + server.getInetAddress() + " P:" + server.getLocalPort()); // 等待客户端链接 for (; ; ) { // 获得客户端 Socket client = server.accept(); // 客户端构建异步线程 ClientHandler clientHandler = new ClientHandler(client); // 启动线程 clientHandler.start(); } } /** * 客户端消息处理 */ private static class ClientHandler extends Thread { private Socket socket; private boolean flag = true; ClientHandler(Socket socket) { this.socket = socket; } @Override public void run() { super.run(); System.out.println("新客户端链接:" + socket.getInetAddress() + " P:" + socket.getPort()); try (// 获得打印流,用于数据输出;服务器回送数据使用 PrintStream socketOutput = new PrintStream(socket.getOutputStream()); // 获得输入流,用于接收数据 BufferedReader socketInput = new BufferedReader(new InputStreamReader( socket.getInputStream()))) { do { // 服务器拿到拿到一条数据 String str = socketInput.readLine(); if ("bye".equalsIgnoreCase(str)) { flag = false; // 回送 socketOutput.println("bye"); } else { // 打印到屏幕。并回送数据长度 System.out.println(str); socketOutput.println("服务器收到了,你发送的长度为 :" + str.length()); } } while (flag); } catch (Exception e) { System.out.println("链接异常断开"); } finally { // 链接关闭 if (socket != null) { try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } } System.out.println("客户端已退出:" + socket.getInetAddress() + " P:" + socket.getPort()); } } }
运行结果:
网络设备
的位置。
IPv4
,IPv6
。