本文主要是本身在网络编程方面的学习总结,先主要介绍计算机网络方面的相关内容,包括计算机网络基础,OSI参考模型,TCP/IP协议簇,常见的网络协议等等,在此基础上,介绍Java中的网络编程。git
1、概述 2、计算机网络 1.网络协议 2.网络体系结构 3、OSI参考模型 4、TCP/IP参考模型 5、常见网络协议 1.TCP协议 2.UDP协议 3.HTTP协议 6、计网常见问题 7、Java网络编程
计算机网络是经过传输介质、通讯设施和网络通讯协议,把分散在不一样地点的计算机设备互连起来,实现资源共享和数据传输的系统。网络编程就就是编写程序使联网的两个(或多个)设备(例如计算机)之间进行数据传输。Java语言对网络编程提供了良好的支持,经过其提供的接口咱们能够很方便地进行网络编程。下面先对网络编程的一些基础知识进行介绍,最后给出使用Java语言进行网络编程的实例。程序员
计算机网络20世纪60年代出现,经历了20世纪70年代、80年代和90年代的发展,进入21世纪后,计算机网络已经成为信息社会的基础设施,深刻到人类社会的方方面面,与人们的工做、学习和生活息息相关。编程
网络协议浏览器
如同人与人之间相互交流是须要遵循必定的规矩同样,计算机之间可以进行相互通讯是由于它们都共同遵照必定的规则,即网络协议。缓存
网络体系结构安全
计算机网络是个复杂的系统,按照人们解决复杂问题的方法,把计算机网络实现的功能分到不一样的层次上,层与层之间用接口链接。通讯的双方具备相同的层次,层次实现的功能由协议数据单元(PDU)来描述。不一样系统中的同一层构成对等层,对等层之间经过对等层协议进行通讯,理解彼此定义好的规则和约定。服务器
计算机网络体系结构是计算机网络层次和协议的集合,网络体系结构对计算机网络实现的功能,以及网络协议、层次、接口和服务进行了描述,但并不涉及具体的实现。接口是同一节点内相邻层之间交换信息的链接处,也叫服务访问点(SAP)。网络
前面咱们介绍了计算机网络的体系结构,由于计算机网络是个复杂的系统,因此把计算机网络实现的功能分到不一样的层次上,而计算机网络体系结构是计算机网络层次和协议的集合。那么,计算机网络如何进行分层呢?下面先介绍的是OSI参考模型。多线程
简介并发
世界上第一个网络体系结构由IBM公司提出(1974年,SNA),之后其余公司也相继提出本身的网络体系结构如:Digital公司的DNA,美国国防部的TCP/IP等,多种网络体系结构并存,其结果是若采用IBM的结构,只能选用IBM的产品,只能与同种结构的网络互联。
为了促进计算机网络的发展,国际标准化组织ISO于1977年成立了一个委员会,在现有网络的基础上,提出了不基于具体机型、操做系统或公司的网络体系结构,称为开放系统互连参考模型,即OSI/RM (Open System Interconnection Reference Model)。OSI模型把网络通讯的工做分为7层,分别是物理层、数据链路层、网络层、传输层、会话层、表示层和应用层。
OSI模型层次功能
物理层处于OSI的最底层,是整个开放系统的基础。物理层涉及通讯信道上传输的原始比特流(bits),它的功能主要是为数据端设备提供传送数据的通路以及传输数据。
数据链路层的主要任务是实现计算机网络中相邻节点之间的可靠传输,把原始的、有差错的物理传输线路加上数据链路协议之后,构成逻辑上可靠的数据链路。须要完成的功能有链路管理、成帧、差错控制以及流量控制等。其中成帧是对物理层的原始比特流进行界定,数据链路层也可以对帧的丢失进行处理。
网络层涉及源主机节点到目的主机节点之间可靠的网络传输,它须要完成的功能主要包括路由选择、网络寻址、流量控制、拥塞控制、网络互连等。
传输层起着承上启下的做用,涉及源端节点到目的端节点之间可靠的信息传输。传输层须要解决跨越网络链接的创建和释放,对底层不可靠的网络,创建链接时须要三次握手,释放链接时须要四次挥手。
会话层的主要功能是负责应用程序之间创建、维持和中断会话,同时也提供对设备和结点之间的会话控制,协调系统和服务之间的交流,并经过提供单工、半双工和全双工3种不一样的通讯方式,使系统和服务之间有序地进行通讯。
表示层关心所传输数据信息的格式定义,其主要功能是把应用层提供的信息变换为可以共同理解的形式,提供字符代码、数据格式、控制信息格式、加密等的统一表示。
应用层为OSI的最高层,是直接为应用进程提供服务的。其做用是在实现多个系统应用进程相互通讯的同时,完成一系列业务处理所需的服务。
OSI参考模型的初衷是提供全世界范围的计算机网络都要遵循的统一标准,可是因为存在模型和协议自身的缺陷,迟迟没有成熟的产品推出。TCP/IP协议在实践中不断完善和发展取得成功,做为网络的基础,Internet的语言,能够说没有TCP/IP协议就没有互联网的今天。
简介
TCP/IP,即Transmission Control Protocol/Internet Protocol的简写,中译名为传输控制协议/因特网互联协议,是Internet最基本的协议、Internet国际互联网络的基础。
TCP/IP协议是一个开放的网络协议簇,它的名字主要取自最重要的网络层IP协议和传输层TCP协议。TCP/IP协议定义了电子设备如何连入因特网,以及数据如何在它们之间传输的标准。TCP/IP参考模型采用4层的层级结构,每一层都呼叫它的下一层所提供的协议来完成本身的需求,这4个层次分别是:网络接口层、互联网层(IP层)、传输层(TCP层)、应用层。
TCP/IP模型层次功能
TCP/IP协议对网络接口层没有给出具体的描述,网络接口层对应着物理层和数据链路层。
互联网层是整个TCP/IP协议栈的核心。它的功能是把分组发往目标网络或主机。同时,为了尽快地发送分组,可能须要沿不一样的路径同时进行分组传递。所以,分组到达的顺序和发送的顺序可能不一样,这就须要上层必须对分组进行排序。互联网层除了须要完成路由的功能外,也能够完成将不一样类型的网络(异构网)互连的任务。除此以外,互联网层还须要完成拥塞控制的功能。
TCP层负责在应用进程之间创建端到端的链接和可靠通讯,它只存在与端节点中。TCP层涉及两个协议,TCP和UDP。其中,TCP协议提供面向链接的服务,提供按字节流的有序、可靠传输,能够实现链接管理、差错控制、流量控制、拥塞控制等。UDP协议提供无链接的服务,用于不须要或没法实现面向链接的网络应用中。
应用层为Internet中的各类网络应用提供服务。
上面主要介绍了OSI参考模型和TCP/IP模型的相关内容,从下面这张图能够看出TCP/IP协议簇中不一样的层次中有着不少不一样的网络协议,下面主要介绍传输层的TCP、UDP协议和应用层的HTTP协议。
TCP协议
TCP(Transmission Control Protocol ,传输控制协议)是面向链接的传输层协议。TCP层是位于IP层之上,应用层之下的中间层。不一样主机的应用层之间常常须要可靠的、像管道同样的链接,可是IP层不提供这样的流机制,而是提供不可靠的包交换。TCP协议采用字节流传输数据。
TCP报文段包括协议首部和数据两部分,协议首部的固定部分有20个字节,首部的固定部分后面是选项部分。
下面是报文段首部各个字段的含义。
TCP是面向链接的协议,所以每一个TCP链接都有3个阶段:链接创建、数据传送和链接释放。链接创建经历三个步骤,一般称为“三次握手”。
TCP三次握手过程以下:
TCP四次挥手过程以下:
因为TCP链接是全双工的,所以每一个方向都必须单独进行关闭。这原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的链接。收到一个 FIN只意味着这一方向上没有数据流动,一个TCP链接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另外一方执行被动关闭。
UDP协议
UDP,用户数据报协议,英文全称是User Datagram Protocol,它是TCP/IP协议簇中无链接的运输层协议。
从图中能够看到,UDP协议十分简单,它由两部分组成:首部和数据。其中,首部仅有8个字节,包括源端口和目的端口,长度(UDP用于数据报的长度)、校验和。
HTTP协议
HTTP,超文本传输协议,英文全称是Hypertext Transfer Protocol,它是互联网上应用最为普遍的一种网络协议。HTTP是一种应用层协议,它是基于TCP协议之上的请求/响应式的协议,即一个客户端与服务器创建链接后,向服务器发送一个请求;服务器接到请求后,给予相应的响应信息。HTTP协议默认的端口号为80.
如今使用的HTTP协议是HTTP/1.1版本,1997年以前采用的是HTTP1.0版本。HTTP链接在1.0版本中采用非持续链接工做方式,1.1版本采用的是持续链接工做方式,持续链接是指服务器在发送响应后仍然在一段时间内保持这条由TCP运输层协议创建起来的链接,使客户机和服务器能够继续在这条链接上传输HTTP报文。
是否采用持续链接工做方式,1.0中默认是关闭的,须要在HTTP头加入"Connection:Keep-Alive",才能启用Keep-Alive。HTTP1.1中默认启用Keep-Alive,若是加入"Connection:close",才关闭。目前大部分浏览器都是用HTTP1.1协议,也就是说默认都会发起Keep-Alive的链接请求了,因此是否能完成一个完整的Keep- Alive链接就看服务器设置状况。
HTTP协议是基于TCP协议之上的请求/响应式协议,下面主要介绍HTTP报文的格式,HTTP报文主要有请求报文和响应报文两种。首先看请求报文的格式:
HTTP请求报文由请求行、首部行和实体主体组成,由浏览器发送给服务器。上面这张图中SP表示空格,cr lf表示回车和换行。
上面这张图是HTTP响应报文,它由状态行、首部行和实体主体组成。下面两张图是在谷歌浏览器内访问服务器查看的HTTP请求和响应。
在上面的HTTP请求报文例子中,咱们能够看到请求方法是GET,这表示请求读取由URL所标志的信息,除了GET,还有其它几种经常使用的方法。
在HTTP响应报文的例子中,咱们能够看到状态码是200,表示响应成功。下表是其它状态码,总共5大类,33种。
HTTPS和HTTP的区别
HTTPS(全称:Hyper Text Transfer Protocol over Secure Socket Layer),是以安全为目标的HTTP通道,简单讲是HTTP的安全版。即HTTP下加入SSL层,HTTPS的安全基础是SSL,所以加密的详细内容就须要SSL。它是一个URI scheme(抽象标识符体系),句法类同http:体系。用于安全的HTTP数据传输。https:URL代表它使用了HTTP,但HTTPS存在不一样于HTTP的默认端口及一个加密/身份验证层(在HTTP与TCP之间)。
超文本传输协议HTTP协议被用于在Web浏览器和网站服务器之间传递信息。HTTP协议以明文方式发送内容,不提供任何方式的数据加密,若是攻击者截取了Web浏览器和网站服务器之间的传输报文,就能够直接读懂其中的信息,所以HTTP协议不适合传输一些敏感信息,好比信用卡号、密码等。
为了解决HTTP协议的这一缺陷,须要使用另外一种协议:安全套接字层超文本传输协议HTTPS。为了数据传输的安全,HTTPS在HTTP的基础上加入了SSL协议,SSL依靠证书来验证服务器的身份,并为浏览器和服务器之间的通讯加密。
HTTPS和HTTP的区别主要为如下四点:一、https协议须要到ca申请证书,通常免费证书不多,须要交费。二、http是超文本传输协议,信息是明文传输,https 则是具备安全性的ssl加密传输协议。三、http和https使用的是彻底不一样的链接方式,用的端口也不同,前者是80,后者是443。四、http的链接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。
到这里,关于计算机网络部分的总结内容就结束了,下面是几个常见的问题,汇总在这里。
OSI参考模型的分为哪几层,每层的功能?
OSI,开放系统互连参考模型,它的7个层次自顶到下依次为应用层,表示层,会话层,传输层,网络层,数据链路层和物理层。各层的功能见文章开始。
TCP协议和UDP协议的区别?
TCP协议是传输控制协议,UDP协议是用户数据报协议,二者都是传输层的协议,主要区别在于前者是可靠的,面向链接的协议,后者是不可靠的,无链接的协议。其它的区别还有,TCP协议传输速度慢,UDP经常使用于一次性传输比较少许数据的网络应用。
TCP三次握手为何不能是两次?
主要是防止两次握手状况下已经失效的链接请求报文段忽然又传送到服务端而产生错误。例如,客户机A向服务器B发送TCP链接请求,第一个链接请求报文在网络的某个节点长时间滞留,A超时后认为报文丢失,因而再重传一次链接请求,B收到后创建链接。数据传输完毕后双方断开链接,而这时以前滞留的链接请求到达了服务端B,而B认为A又发来链接请求。若是两次握手创建链接,A并没有链接请求,形成B的资源浪费。
HTTP请求的GET方法和POST方法的区别?
GET和POST是HTTP请求的两种方法,主要区别在于GET方法是请求读取由URL所标志的信息,POST是给服务器添加信息。点击查看更多
在浏览器中输入网址到显示出页面的整个过程?
(1) 输出包含域名的网址 (2) 浏览器向DNS请求解析域名对应的IP地址 (3) 域名系统DNS解析出域名对应的IP地址 (4) 浏览器与该服务器创建TCP链接 (5) 浏览器发送HTTP请求 (6) 服务器经过HTTP响应把页面文件发送给浏览器 (7) TCP链接释放 (8) 浏览器解释文件,并显示
Java的网络编程主要涉及到的内容是Socket编程,那么什么是Socket呢?简单地说,Socket,套接字,就是两台主机之间逻辑链接的端点。TPC/IP协议是传输层协议,主要解决数据如何在网络中传输,而HTTP是应用层协议,主要解决如何包装数据。Socket,本质上就是一组接口,是对TCP/IP协议的封装和应用(程序员层面上)。
总体流程
Socket编程主要涉及到客户端和服务器端两个方面,首先是在服务器端建立一个服务器套接字(ServerSocket),并把它附加到一个端口上,服务器从这个端口监听链接。端口号的范围是0到65536,可是0到1024是为特权服务保留的端口号,咱们能够选择任意一个当前没有被其余进程使用的端口。
客户端请求与服务器进行链接的时候,根据服务器的域名或者IP地址,加上端口号,打开一个套接字。当服务器接受链接后,服务器和客户端之间的通讯就像输入输出流同样进行操做。
实例一
下面是一个客户端和服务器端进行数据交互的简单例子,客户端输入正方形的边长,服务器端接收到后计算面积并返回给客户端,经过这个例子能够初步对Socket编程有个把握。
public class SocketServer { public static void main(String[] args) throws IOException { // 端口号 int port = 7000; // 在端口上建立一个服务器套接字 ServerSocket serverSocket = new ServerSocket(port); // 监听来自客户端的链接 Socket socket = serverSocket.accept(); DataInputStream dis = new DataInputStream( new BufferedInputStream(socket.getInputStream())); DataOutputStream dos = new DataOutputStream( new BufferedOutputStream(socket.getOutputStream())); do { double length = dis.readDouble(); System.out.println("服务器端收到的边长数据为:" + length); double result = length * length; dos.writeDouble(result); dos.flush(); } while (dis.readInt() != 0); socket.close(); serverSocket.close(); } }
public class SocketClient { public static void main(String[] args) throws UnknownHostException, IOException { int port = 7000; String host = "localhost"; // 建立一个套接字并将其链接到指定端口号 Socket socket = new Socket(host, port); DataInputStream dis = new DataInputStream( new BufferedInputStream(socket.getInputStream())); DataOutputStream dos = new DataOutputStream( new BufferedOutputStream(socket.getOutputStream())); Scanner sc = new Scanner(System.in); boolean flag = false; while (!flag) { System.out.println("请输入正方形的边长:"); double length = sc.nextDouble(); dos.writeDouble(length); dos.flush(); double area = dis.readDouble(); System.out.println("服务器返回的计算面积为:" + area); while (true) { System.out.println("继续计算?(Y/N)"); String str = sc.next(); if (str.equalsIgnoreCase("N")) { dos.writeInt(0); dos.flush(); flag = true; break; } else if (str.equalsIgnoreCase("Y")) { dos.writeInt(1); dos.flush(); break; } } } socket.close(); } }
实例二
能够看到上面的服务器端程序和客户端程序是一对一的关系,为了能让一个服务器端程序能同时为多个客户提供服务,可使用多线程机制,每一个客户端的请求都由一个独立的线程进行处理。下面是改写后的服务器端程序。
public class SocketServerM { public static void main(String[] args) throws IOException { int port = 7000; int clientNo = 1; ServerSocket serverSocket = new ServerSocket(port); // 建立线程池 ExecutorService exec = Executors.newCachedThreadPool(); try { while (true) { Socket socket = serverSocket.accept(); exec.execute(new SingleServer(socket, clientNo)); clientNo++; } } finally { serverSocket.close(); } } } class SingleServer implements Runnable { private Socket socket; private int clientNo; public SingleServer(Socket socket, int clientNo) { this.socket = socket; this.clientNo = clientNo; } @Override public void run() { try { DataInputStream dis = new DataInputStream( new BufferedInputStream(socket.getInputStream())); DataOutputStream dos = new DataOutputStream( new BufferedOutputStream(socket.getOutputStream())); do { double length = dis.readDouble(); System.out.println("从客户端" + clientNo + "接收到的边长数据为:" + length); double result = length * length; dos.writeDouble(result); dos.flush(); } while (dis.readInt() != 0); } catch (IOException e) { e.printStackTrace(); } finally { System.out.println("与客户端" + clientNo + "通讯结束"); try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } } }
上面改进后的服务器端代码能够支持不断地并发响应网络中的客户请求。关键的地方在于多线程机制的运用,同时利用线程池能够改善服务器程序的性能。
做者:尘语凡心连接:http://www.jianshu.com/p/ae5e1cee5b04來源:简书著做权归做者全部。商业转载请联系做者得到受权,非商业转载请注明出处。