参考:1. 孙卫琴 Java 网络编程 2. 非常经典的动物系列封面的 具体叫什么忘了 3.网上一些博客,地址忘了记了。
从今天开始写博,自我感觉看书有一定局限性,网上博客有很多精彩的,也希望自己记录一些自己的一些理解。
本人小白,欢迎拍砖与交流。
一. 基本kownlege
1.什么是网络编程????
网络编程就是在两个或两个以上的设备(例如计算机)之间传输数据,更具体的说,网络编程就是两个或多个程序之间的数据交换。
2. IP和端口
这个没什么好解释的。你想泡美眉先要搞到电话地址吧。你想进行网络通讯没ip端口怎么行?
网络中的每个设备都会有一个唯一的数字标识,这个就是IP地址。这个没什么好解释的。
为了方便记忆,有创造了另外一个概念——域名(Domain Name),例如sp2wapi.qa.webex.com等。
为了让一个计算机可以同时运行多个网络程序,就引入了另外一个概念——端口(port)。在同一个计算机中每个程序对应唯一的端口。
这样就实现了一个计算机上可以并发运行多个网络程序,而不会在互相之间产生干扰。
3.c/s和b/s
虽然通过IP地址和端口可以找到网络上运行的一个程序,但是如果需要进行网络编程,则还需要了解网络通讯的过程???
网络通讯基于“请求-响应”模型。
例如QQ程序,QQ用户安装的都是QQ客户端程序,QQ服务器端程序则运行在腾讯公司的机房中。这种网络编程的结构叫做Client/Server结构,简称C/S结构。
在运行很多程序时,没有必要使用专用的客户端,而需要使用通用的客户端,例如浏览器,使用浏览器作为客户端的结构叫做Browser/Server结构,简称为B/S结构。
4.TCP/IP四层模型
对于java的网络程序而言,OSI参考模型的过于庞大、复杂,java的网络类只工作在TCP/IP网络中,始终运行在应用层和传输层,所以我们只关心适用于internet标准的TCP/IP四层模型。
1)网络接口层
连接不同计算机的硬件组成了网络接口层,它定义了某个网络接口如何通过与本地网络或世界其他部分的物理连接发送IP数据报。
作为java 程序员,不需要担心这一层,java从来都看不到物理层。
2)网络层
网络层是整个TCP/IP协议栈的核心。它的功能是把分组发往目标网络或主机。同时,为了尽快地发送分组,可能需要沿不同的路径同时进行分组传递。因此,分组到达的顺序和发送的顺序可能不同,这就需要上层必须对分组进行排序。
网络层定义了分组格式和协议,即IP协议(Internet Protocol)。IP协议是世界上使用最广泛的网络层协议。
网络层也可以完成将不同类型的网络(异构网)互连的任务。
3)传输层
数据报并非是顺序到达,在传送中也可能遭到破坏,传输层负责确保包的顺序接收,没有数据丢失和破坏。为了实现这个目标,IP网络给每个数据报的首部添加了更多的信息。
这一层主要有两个协议:TCP,UDP.
TCP协议是一个面向连接的、可靠的协议。它将一台主机发出的字节流无差错地发往互联网上的其他主机。在发送端,它负责把上层传送下来的字节流分成报文段并传递给下层。在接收端,它负责把收到的报文进行重组后递交给上层。TCP协议还要处理端到端的流量控制,以避免缓慢接收的接收方没有足够的缓冲区接收发送方发送的大量数据。(开销高)
UDP协议是一个不可靠的、无连接协议,主要适用于不需要对报文进行排序和流量控制的场合。 4)应用层
应用层下面的三层共同定义了数据如何传输,应用层确定了数据传输后的操作。
应用层的主要任务是应用。负责实现一切和应用程序相关的功能,为操作系统或网络应用程序提供访问网络服务的接口。
应用层就是应用层的应用程序和应用层协议的综合应用,两者缺一不可。
比如,你要上网,你输入了www.baidu.com,那么这个时候你就用了浏览器这个应用程序和HTTP以及DNS这两个应用层协议,你想想,没有浏览器你如何浏览网页,单靠HTTP和DNS协议能打开网站吗?
比如,你要上网,你输入了www.baidu.com,那么这个时候你就用了浏览器这个应用程序和HTTP以及DNS这两个应用层协议,你想想,没有浏览器你如何浏览网页,单靠HTTP和DNS协议能打开网站吗?
我画了粗燥的图,图描述了web浏览器向web服务器发送请求,每一层具体干什么。
二.客户端 sokect
数据在internet中是以数据报来传输,怎么来将数据报来分解成包,生成首部,解析等等,这是个相当繁杂的工作。但是幸运的是我们不用来完成这些工作,socket类掩盖了这些细节,让网络连接变成一种可以读取字节的流。Socket类就是对Socket的具体实现。它通过连接到主机后,返回一个I/O流,实现协议间的信息交换。
它可以进行七项基本操作:
•连接远程机器
•发送数据
•接收数据
•关闭连接
•绑定端口
•监听入站数据
•在所绑定端口上接受来自远程机器的连接
1.用构造函数创建一个新socket
Socket的构造方法有一下几种重载方式:
•1) public Socket(String host, int port) throws UnkownHostException, IOException
•2) public Socket(InetAddress host, int port) throws IOException
•3) public Socket(String host, int port, InetAddress interface, int localPort) throws IOException, UnkownHostException
•4) public Socket(String host, int port, InetAddress interface, int localPort) throws IOException
•5)protected Socket ()
•6) protected Socket (SocketImpl impl)
•7) public Socket(Proxy proxy) //java 1.5
2.获取Sockect的有关信息
•1).public InetAddress getInetAddress()
•2).public int getPort()
•3).public int getLocalPort()
•4).public InetAddress getLocalAdress()
•5).public InputStream getInputStream() throws IOException
•6). public OutputStream getOutputStream() throws IOException
getInetAddress():获得远程服务器的IP地址。
getPort():获得远程服务器的端口。
getLocalAddress():获得客户本地的IP地址。
getLocalPort():获得客户本地的端口。
getInputStream() :获得输入流。客户端的Socket对象上的getInputStream方法得到的输入流其实就是从服务器端发回的数据流。
getOutputStream() :获得输出流。客户端Socket对象上的getOutputStream方法返回的输出流就是将要发送到服务器端的数据流 。
3.关闭Socket
Public void close() throw IOException
用法:
try
{
connection=new Socket(“****”,**)
}
Catch (IOException ex)
{
System.err.println(ex);
}
Finally{
if (connection!=null)
{connection.close();}
}
半关闭Socket :
如果只想关闭连接的一半,输入或输出。
public void shutdownInput() throws IOEXception
public void shoutdownOuput() throws IOEXception
Tips:半关闭连接之后,仍要关闭该socket。
4. 设置socket选项
1)TCP-NODELAY:
public void setTcpNoDelay(boolean on) throws SocketException
设置TCP-NODELAY为true,可确保包尽快发出去.
一个有趣的例子:http://www.cnblogs.com/brucexu/archive/2012/05/03/2481353.html
2)SO_LINGER :
public void setSoLinger (boolean on, int seconds) throws SocketException
当closesocket后,SO_LINGER将决定系统如何处理残存在套接字发送队列中的数据。处理方式有两种:丢弃或者将数据继续发送至对端,关闭连接。事实上,SO_LINGER并不被推荐使用,大多数情况下我们推荐使用默认的关闭方式
3)SO_TIMEOUT
public void setSoTimeout (int milliseconds) throws SocketException
在尝试读取socket时,read()会阻塞尽可能长的时间,设置SO_TIMEOUT可保证此次调用不会超过设置时间.
4)SO_RCVBUF
public void setSendBufferSize(int size)
可设置socket输入缓冲所使用的字节数,这个字段决定了一次能从socket里读取的字节数。
5)SO_KEEPALIVE
public void setKeepAlive(boolena on)throws SocketException
如果启用,客户端会俩小时发生一次数据包,确保服务器未崩溃,如在12分钟内没有收到相应,客户端会关掉socket.
6)OOBLINLINE
public void sendUrgentData(int date) throws IOEXception
可发送紧急数据,但是只处理一位。不建议使用, 一般说如果你有紧急数据宁愿再建立一个新的TCP/IP连接发送数据,让对方紧急处理
可发送紧急数据,但是只处理一位。不建议使用, 一般说如果你有紧急数据宁愿再建立一个新的TCP/IP连接发送数据,让对方紧急处理
7)SO_REUSEADDR
public void setReuseAddress(boolean on ) throws SocketEXCeption
如果想重用一个未完全释放地址的sokect, 旧的socket和新的socket都要已经被设置了SO_REUSEADDR特性
三. 服务器sokect
服务器的生命周期:
•1.使用ServicerSocket()构造函数在某个端口创建新的ServicerSocket
•2.ServicerSockect用accept()方法监听端口。accept()会一直阻塞,直到客户端尝试连接,这时,accept()会返回一个连接客户端和服务器的Socket对象。
•3.用Socket的getInputStream() 或getOutputStream()获得输入输出流。
•4.客户端和服务器根据协商的协议交互,直到关闭连接。
•5.关闭连接
•6.服务器返回2,等待下一次连接
1.构造函数
•pubilc ServerSocket(int port) throws BindException,IOException
•public ServerSocket(int port,int queueLength) throws IOException,BindExeption
•public ServerSocket(int port,int queueLength,InetAddress bindAddress) throws BindException,IOException
• public ServerSocket() throws IOException
2.接受和关闭连接
Public Socket accept() throws IOException
ServerSocket通常在循环中重复接受连接,accept()方法是阻塞的,直到有客户连接时,会返回一个Scoket对象。之后就可以用getInputStream()和getOutputStream()来与客户端进行通信,如不想在等待连接时停止程序,就将accept()调用放在单独的线程中。
Public void close() throws IOException
Java1.4还添加了isClosed,isBound方法。
四.URL类
Java.net.URL类是对同一资源定位符的抽象。为了处理方便, Java将URL封装成URL类, 我们可以用一个URL对象记录下完整的URL信息。 是个final类不能派生子类。也就是说不依赖于继承来配置URL,而是使用策略设计模式。
URL是个对象,不是字符串,包括协议,主机名,端口等字段,可用URL构造函数来设置这些字段
URL字段只对java.net包中的其他成员可见。
在构造URL后,其字段就不可再改变。
1.创建一个新的URL
1).通过字符串构造
public URL(String url) throws MalformedURLException
2).通过各个部分构造URL
public URL(String protocol,String hostname,String file) throws MalformedURLException
3).构造相对的URL
public URL(URL base,String relative)throwsMalformedURLException
常用于对于处理同一个目录下的文件
4).指定一个URLStreamHandler
public URL(String protocol,String host,int port ,String file ,URLStreamHandler handler) throwsMalformedURLException
public URL(URL base,String relative, URLStreamHandler handler) throwsMalformedURLException
当操作某个虚拟机不存在的URL模式或添加默认的流处理器未提供的功能,这个就非常有用。
2.分解URL
•public String getProtocol()
•public String getHost()
•public String getPort()
•public String getDefaultPort()
•public String getFile()
•public String getPath()
•public String getRef()
•public String getQuery()
•public String getUserInfo()
•public String getAuthority()
3.从URL获取数据
public InputStreamopenStream() throws IOException
public URLConnectionopenConnection() throws IOException打开指定URL的Socket,返回一个URLConnection的对象。
public URLConnectionopenConnection(Proxy proxy) throws IOException可指定连接通过的代理服务器
public object getContent() throws IOException获取URL指向的数据
public object getContent(Class[] classes) throws IOException尝试以数据的顺序返回URL的内容
五.URLConnection类
URLConnection是一个抽象类,代表与URL指定的数据源的动态连接,URLConnection类提供比URL类更强的服务器交互控制。URLConnection允许用POST或PUT和其他HTTP请求方法将数据送回服务器。
1.使用URLConnection对象的一般方法
(1)创建一个URL对象。
(2)调用URL对象的openConnection()方法创建这个URL的URLConnection对象。
(3)配置URLConnection。
(4)读首部字段。
(5)获取输入流并读数据。
(6)获取输出流并写数据。
(7)关闭连接。