分享
 
 
 

终结Oreilly的《Java网络编程》-UDP包与URLConnection(部分)

王朝java/jsp·作者佚名  2006-02-01
窄屏简体版  字體: |||超大  

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

allowUserInteraction

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

connected

If false, this connection object has not created a communications link to the specified URL.

protected boolean

doInput

This variable is set by the setDoInput method.

protected boolean

doOutput

This variable is set by the setDoOutput method.

protected long

ifModifiedSince

Some protocols support skipping the fetching of the object unless the object has been modified more recently than a certain time.

protected URL

url

The URL represents the remote object on the World Wide Web to which this connection is opened.

protected boolean

useCaches

If true, the protocol is allowed to use caching whenever it can.

这些属性准确地定义了客户机如何向服务器发出请求;

有一系列的get,set方法来配制;

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有