TCP的做法:
1, 如果数据在传输过程中丢失或者损坏,TCP协议可以保证恢复数据;
2, 如果数据在到达目的端时顺序出错,TCP协议可以恢复正确的顺序;
3, 如果传输数据流的速度超出TCP协议的链接能力,TCP协议能够降低传输速率;
但是这一切都是以降低数据传输率为代价的。
UDP:
无法保证数据是否可以到达目标主机;
无法知道数据是否按照发送顺序到达目标端;
UDP也可以实现可靠传输,通常的做法是把数据的确认工作放到应用层,由应用层程序来实现上面所说的TCP的三个做法;但是这样很复杂,而且你怎么保证你写的应用层程序会比TCP做的好呢?这几类似于邮政系统是个UDP,而电话系统是TCP,邮政系统不提供当邮件发送失败的时候重新再发的服务,也不会保证发的所有邮件会按发送的前后顺序到达目的地;但是这不代表我们利用邮政系统做不到电话系统的两个特点:确认听到对方的声音以及说的话会按顺序传给对方。我们完全可以在自己发的邮件上写上一句话:“你Y收到信后给我回一信,以保证在你没收到时我给你重发”,还可以给我们发送的多个邮件编号,让收到信的人按照这个编号重新排列信件;所以说UDP可以做到和TCP完全相同的效果,只是对应用层程序员来说,那样的工作不象TCP那么自动化,那么简单;
DatagramPacket类
在Java中,UDP数据报可以用一个类的实例来代表:
Public fianl class DatagramPacket extends Object
构造器:
1,接受数据报的构造器:
Public DatagramPacket(byte[] buffer,int length)
Public DatagramPacket(byte[] buffer,int offset,int length)
意思是将收到的数据报的数据部分从buffer的buffer[0]开始依次存放知道满length个为止;
2,发送数据报的构造器:
Public DatagramPacket(byte[] data,int length,InetAddress destiination,int port)
Public DatagramPacket(byte[] data,int offset,int length,InetAddress destiination,int port)
意思是byte数组里的length个字节的数据将要被发送到destiination主机上的port端口;
非常令人欣慰的是,当我们创建一个DatagramPacket对象后,如果想要改变它的data,length,destiination,port的话,并不需要重新构造对象,因为DatagramPacket类提供了一系列的get和set方法来动态更新数据报;
URLConnection代表与URL指定的数据源的动态连接。
URLConnection类与HTTP协议密切相关,它假定在每个文件传输之前先传送一个MIME首部,但是FTP等协议并不发MIME首部;
URLConnection是抽象的;
当获得一个URLConnection对象的时候,并没有连接到远程主机,直到调用它的方法connect()后,将在本地主机和远程主机之间建立一个连接,通常是TCP套接字实现的连接;
getInputStream(),getContent(),getHeaderField()等方法在没有打开连接的情况下会自己调用connect()方法,所以用户很少自己调用connect();
你发现用Socket连接到HTTP服务器的时候,总是得先给它发送一个正规的HTTP请求,它才有反应;而URLConnection一旦得到一个InputStream()就好了,数据已经到了,
这说明URLConnection和浏览器一样贱!
getInputStream()得到的一个输入流里只有数据部分,没有什么头啊首部之类的;
但是我们可以用别的方法来获得
读首部
Public String getContentType()
Public String getContentLength() 我们可以用这样的办法下载文本文件:
Int c;
While((c=in.read())!=-1)
…….
理论上虽然也可以用同样的办法下载二进制文件,但是因为HTTP服务器总不会总是在用户需要的时候就关闭连接并且发送一个 EOF字符到用户,因此,用户并不知道什么时候读操作结束;更可靠的办法是用getContentLength()先找到文件的长度,然后读出length个字节;
比如这样读:
int byteRead=0;
int offset=0;
int count=0;
while(offset<contentLength)
{
byteRead=in.read(data,offset,data.length-offset);
if(byteRead==-1)
break;
offset+=byteRead;
}
也许你也发现了,BufferedInputStream.read(byte[],offset,length)方法需要循环读取,下面是文档的解释:
This method implements the general contract of the corresponding ,]read method of the InputStream class. As an additional convenience, it attempts to read as many bytes as possible by repeatedly invoking the read method of the underlying stream. This iterated read continues until one of the following conditions becomes true:
· The specified number of bytes have been read,
· The read method of the underlying stream returns -1, indicating end-of-file, or
· The available method of the underlying stream returns zero, indicating that further input requests would block.
If the first read on the underlying stream returns -1 to indicate end-of-file then this method returns -1. Otherwise this method returns the number of bytes actually read.
Public String getContentEncoding()
Public long getDate()
Public long getExpiration()
Public long getLastModified()
检索临时MIME首部字段
上面所描述的过于固定也过于不灵活,我们有更动态的方法来获得MIME首部字段:
Public String getHeaderField(String name)
Name= Content-type;
Content-encoding;
Date;
Expires;
Content-length;
Public String getHeaderFieldKey(int n)返回第n个MIME首部字段的键(字段名);
Public String getHeaderField(int n)返回第n个MIME首部字段的值;
注意:第一个字段是1而不是0;
Public long getHeaderFieldDate(String name,long default) 适合date
Publi int getHeaderFieldInt(String name,int default) 适合length
这两个方法都试图把键为name的字段的值转化为long或者int返回,如果失败就用default返回;
配制连接属性:
protected boolean
If true, this URL is being examined in a context in which it makes sense to allow user interactions such as popping up an authentication dialog.
protected boolean
If false, this connection object has not created a communications link to the specified URL.
protected boolean
This variable is set by the setDoInput method.
protected boolean
This variable is set by the setDoOutput method.
protected long
Some protocols support skipping the fetching of the object unless the object has been modified more recently than a certain time.
protected URL
The URL represents the remote object on the World Wide Web to which this connection is opened.
protected boolean
If true, the protocol is allowed to use caching whenever it can.
这些属性准确地定义了客户机如何向服务器发出请求;
有一系列的get,set方法来配制;