Java网络通信程序的设计.ppt

上传人:za****8 文档编号:7179904 上传时间:2020-03-15 格式:PPT 页数:119 大小:648.52KB
返回 下载 相关 举报
Java网络通信程序的设计.ppt_第1页
第1页 / 共119页
Java网络通信程序的设计.ppt_第2页
第2页 / 共119页
Java网络通信程序的设计.ppt_第3页
第3页 / 共119页
点击查看更多>>
资源描述
第11章Java网络通信程序的设计 11 1处理URL内容11 2使用Socket通信11 3使用UDP通信 11 1处理URL内容 URL UniformResourceLocator 是Internet的关键部分 它提供了人和机器的导航 其功能是指向计算机里的资源 即定位 URL可以分成三个部分 通信协议 计算机地址和文件 URL常见的通信协议有三种 http ftp和file 所谓通信协议 就是客户端计算机与服务器端计算机在网络上通信的方法 有时候在地址后面还要指定使用哪一个端口 Port 例如 80 index html 如果URL没有指定使用哪一个端口 则会根据通信协议使用默认的端口 一般地 http协议默认端口为80 ftp协议默认端口为21 包中包含两个专门用于URL的关键类 即URL和URLConnection URL和URLConnection类封装了检索远程站点信息的操作 因而大大地降低了这些操作的复杂性 下面几节将介绍这两个类 11 1 1URL类的基本方法URL类提供的最基本的网络功能是以流的形式读取URL所指的的数据 URL类的实例可以用表示URL的文本串来建立 以表示URL所指的数据 构造一个URL类实例的最简单方法是为URL构造方法赋予一个字符串 URLurl newURL URLdata newURL url data data html 这种构造方法指定了位于url的data子目录中的data html文件 它的绝对地址应该是 注 URL类既支持http协议 也支持ftp和file协议 如果URL文本有错或者Java平台不支持其协议部分 则这个构造函数抛出一个MalformedURLException 该Exception是java io IOException的子类 指出给定的是不合法的URL 通常应通过try catch块处理或声明让调用方法传递这个异常 URL类常用的构造函数有下列三种 URL Stringspec throwsMalformedURLException创建一个由spec指定的URL类的实例 URL Stringspec Stringhost intport Stringfile throwsMalformedURLException创建一个URL类的实例 分别指定其通信协议 protocal 计算机地址 host 连接端口 port 和文件 file 如果port值是 1 则表示使用默认端口 URL Stringprotocal Stringhost Stringfile throwsMalformedURLException功能同上 但没有指定端口 即使用默认的端口 URL类的一些主要方法如下 publicStringgetFile 返回URL中的文件部分 publicStringgetHost 返回URL中的计算机地址部分 publicintgetPort 返回URL中所使用的端口 publicStringgetProtocal 返回URL中通信协议的部分 下面是一个使用URL类及其方法的例子 例11 1URLDemo javaimportgenesis publicclassURLDemo publicstaticvoidmain Stringargs try 创建一个指向首页的URL类的实例URLurl newURL Transcript println Protocol url getProtocol Transcript println Host url getHost Transcript println Port url getPort Transcript println File url getFile catch MalformedURLExceptione Transcript println 错误的URL 这个例子很简单 因为没有指定URL的连接端口 所以显示值为 1 实际连接时 会根据通信协议而决定使用哪一个端口 它的运行结果如图11 1所示 图11 1 11 1 2用URL类实现页面的访问一旦构造了URL 就可以用URL类中的openStream 方法读取URL描述的数据 openStream 打开一个到URL类指定资源的连接 并返回一个InputStream对象 利用这个对象 可以方便的读取资源的内容 也可以链接到其他类型的输入流和读取器上 我们来看一个读取页面内容的例子 例11 2GetPage javaimportgenesis importjava io publicclassGetPage publicstaticvoidmain Stringargs try URLurl newURL InputStreamin url openStream BufferedReaderreader newBufferedReader newInputStreamReader in 打开index hmtl文件为写做准备FileWriterfw newFileWriter index html PrintWriterpw newPrintWriter fw Stringline 逐行读入页面内容while line reader readLine null 将读入的行保存到index html文件pw println line 将读入的行显示在窗口中Transcript println line reader close pw close fw close catch IOExceptione Transcript println e getMessage 程序的运行结果如图11 2所示 图11 2 上面的例子通过读取的首页index html 展示了怎样通过URL访问Web页面的内容 图11 2窗口中显示的就是index html页面所包含的内容 即它的源码 该例中将读入的内容保存在当前目录下 名为index html的文件中 用浏览器打开这个文件 可以看到如同访问的页面 但是 无法看到页面中的图片 因为打开的输入流只读入了页面的内容 并没有将图片链接也读入进来 打开index html文件将看到如图11 3所示的页面 图11 3 11 1 3用URLConnection类实现页面的访问我们已经知道了如何通过URL类访问URL资源 但如果想了解关于这个资源的更多信息 就需要使用URLConnection类 URLConnection类提供了访问网络资源时更多 更好的控制方法 使用URLConnection类来访问Web页面的步骤如下 1 调用URL类的openConnection 方法得到一个URLConnection类的实例 URLConnectionconn url openConnection 2 调用以下方法 设置所有相关属性 setAllowUserInteraction setDoInput setDoOutput setIfModifiedSince setUseCaches setRequestProperty 3 调用connect 方法连接远程资源 conn connect connect 方法除了创建一个连接指定服务器的套接字连接外 还可以查询服务器以获取相应头信息 headerinformation 4 连接服务器以后 使用getHeaderFieldKey 和getHeaderField 方法来枚举出头信息的所有域 此外 也可以使用如下的方法来查询标准域的内容 getContentEncoding getContentLength getContentType getData getExpiration getLastModified 5 使用getInputStream 方法访问资源数据 用getInputStream 方法将返回一个输入流 此输入流和URL类的openStream 方法返回的输入流是相同的 下面我们将详细的介绍其中的一些方法 在用于连接服务器前设置连接属性 第 2 步 的几个方法中 setDoInput 和setDoOutput 这两个方法最为重要 缺省时 连接服务器后将产生一个用于读取服务器数据的输入流 但不会产生用于向服务器写出数据的输出流 如果需要用到一个输出流 例如 用于向CGIForm发送数据 就必须调用conn setDoOutput true setIfModifiedSince 方法用于告诉连接 只需要在给出的日期之后被修改过的数据 setUseCaches 和setAllowUserInteraction 方法只用于Applet setUseCaches 方法指示浏览器先检查它的高速缓存区 这样可以优化访问 如果设置其值为false 将不使用浏览器的缓存 其默认值为true setAllowUserInteraction 允许Applet弹出一个查询用户名和密码的对话框 这些设置在Applet外部不起作用 setRequestProperty 方法设置一个名字 值对 用于说明某一特定的协议 例如 想访问一个口令保护的网页 必须进行如下设置 Stringinput username password conn setRequestProperty Authorization Basic input 注 用ftp协议访问一个有口令保护的文件时 将使用和上面完全不同的方法 只需要创建一个如下形式的URL ftp username password 例11 3GetHeaderField javaimportgenesis importjava io publicclassGetHeaderField publicstaticvoidmain Stringargs try URLurl newURL 得到一个URLConnection对象URLConnectionconn url openConnection 连接服务器conn connect inti 1 Stringkey Stringvalue 逐一读出指定URL中的所有域while key conn getHeaderFieldKey i null 读出对应域的值value conn getHeaderField i Transcript println key value i 获取一个输入流InputStreamin conn getInputStream BufferedReaderreader newBufferedReader newInputStreamReader in 打开index hmtl文件为写做准备FileWriterfw newFileWriter index html PrintWriterpw newPrintWriter fw Stringline 逐行读入页面内容while line reader readLine null 保存到index html文件中pw println line reader close pw close fw close catch IOExceptione Transcript println e getMessage 程序的运行结果如图11 4所示 图11 4 以上输出结果展示了一个典型的HTTP请求的响应头所包含的一组域 getHeaderFieldKey 和getHeaderField 方法分别返回响应头中指定位置的域名和值 指定值基数为1 当指定值为零或大于头中域总数时 将返回null串 由于URLConnection类中没有提供获得相应头中域总数的方法 所以需重复调用getHeaderFieldKey 方法 直到返回null串来确定头中域的总数 程序中同时演示了如何通过URLConnection类获取页面内容 调用URLConnection类的方法getInputStream 将返回一个InputStream类的实例 这个对象和调用URL类中openStream 返回的InputStream对象是相同的 利用这个对象 我们可以建立一个获取页面内容的输入流 运行例子后 当前目录将会生成一个index html文件 通过浏览器打开这个文件 可以看到 结果和前面通过URL访问页面内容所得到的结果相同 此外 为了便于查询最常见的响应头域的值 Java库提供了六个更为方便的方法直接访问这些域 如表11 1所示 表11 1直接获取指定域值的方法 11 1 4与CGI的沟通在Java技术出现之前 用CGI CommonGatewayInterface 来提供相互交换网络数据的方法就已广泛使用 把信息从网络浏览器发送给相应的网络服务器 例如使用电子邮件服务 通常需要填写用户名和提交密码 传统的HTML语言提供了Form标记发送格式数据 一个典型的HTMLForm描述如例11 4 例11 4form htmlName EmailAddress 通过在浏览器上打开输入以上代码的html文件 我们可以看到一个如图11 5所示的页面 图11 5 在Internet上访问邮件服务时 用户需要填写一个类似上图的表单 当用户点击提交按键后 浏览器将会发送这些填写的数据到action属性指定的服务器中的CGI程序 CGI程序负责处理这些数据 然后生成一个HTML页面 并送回浏览器 对于邮件服务 这个新的响应页通常就是我们登陆后的页面 有关CGI程序和HTMLForm的详细内容 本章将不再继续讨论 如需了解可参考有关书籍 除了处理传统的非交互式类型外 URLConnection类也提供了用于CGI或Servlet连接的功能 和HTML表单页一样 Java程序可以向服务器发出一个CGI请求 这个请求既可以设为GET 也可以设为POST 此外 也可在程序中拦截CGI程序的输出 所以通过Java程序可以实现和CGI程序交互信息的全部过程 通过GET方法向CGI程序发送信息时 只需将参数置于URL的末尾 并用 分隔 URL的基本格式为http host script parameters当包含两个以上的参数时 用一个 分开每个参数 并对参数做以下的编码处理 用 代替所有的空格 用 加两位十六进制数代替所有非字母的字符 包括汉字 例如 假设一个参数为 C Language 它将被编码为 C 2b 2b Language 其中2b 十进制数43 就是ASCII码的 字符 这种编码方法避免了空格干扰 并可以解释其他字符 这种编码方式称为URL编码 GET方法非常方便 但是有一个大的限制 就是浏览器一般会限制GET请求的URL串的字符个数 而POST的方法则不同 使用POST请求的时候 不把参数放在URL的末端 而是采用建立一个到服务器的输出流的方式 通过得到一个来自URLConnection的输出流 并把参数名 值对逐个写入到输出流 就可以实现POST方法的请求 使用POST方法时 仍需用URL编码方式处理这些输入的参数 并用 将参数分开 下面我们仍然通过一个例子来详细的了解GET和POST方法与CGI通信的过程以及它们的不同之处 例11 5CGITest javaimportgenesis importjava io importjava util publicclassCGITest URLurl null URLConnectionconn null FileWriterfw null PrintWriterpw null publicstaticvoidmain String args CGITesttest newCGITest ArrayListparam newArrayList if args 0 equals GET args 0 equals get GET方法所需要的参数param add p param add args 1 param add u param add B GET方法通过Yahoo提供的搜索引擎搜索给定的关键字test doGet if args 0 equals POST args 0 equals post POST方法所需要的参数param clear param add user param add args 1 param add pass param add args 2 param add type param add 0 param add verifycookie param add y POST方法登陆163邮箱test doPost publicStringdoGet Stringlocation java util Listparam if param null StringBufferbufParam newStringBuffer 通过一个枚举器列出所有参数Iteratoriterator param iterator Stringkey null Stringvalue null 枚举出所有的参数while iterator hasNext key String iterator next value String iterator next 对参数进行编码 然后转化成key value的格式 并将它们串在一起 通过 if iterator hasNext bufParam append try url newURL location conn url openConnection 连接服务器conn connect 得到一个输入流InputStreamin conn getInputStream BufferedReaderreader newBufferedReader newInputStreamReader in 打开Get html文件准备写fw newFileWriter Get html pw newPrintWriter fw Stringline 逐行读入while line reader readLine null page append line n pw println line pw close fw close reader close in close catch IOExceptione Transcript println e getMessage returnpage toString publicStringdoPost Stringlocation java util Listparam StringBufferpage newStringBuffer try url newURL location conn url openConnection 同时打开到服务器的输入和输出流conn setDoOutput true conn setDoInput true if param null 获取一个到服务器的输入通道PrintWriterout newPrintWriter conn getOutputStream Iteratoriterator param iterator Stringkey null Stringvalue null 枚举列出所有参数while iterator hasNext 对参数进行编码 并逐个将参数转化成 key value的格式 直接输出到服务器key URLEncoder encode String iterator next value URLEncoder encode String iterator next out print key value if iterator hasNext out print 获取一个输入流InputStreamin conn getInputStream BufferedReaderreader newBufferedReader newInputStreamReader in 打开Post html准备写fw newFileWriter Post html pw newPrintWriter fw Stringline 逐行读入 while line reader readLine null page append line n pw println line pw close fw close reader close in close catch IOExceptione Transcript println e getMessage returnpage toString 这个例子比较长 但它并不复杂 程序中 通过两个方法 doGet 和doPost 分别实现了GET和POST两种方式与CGI的通信 在doGet 方法中 测试的是使用Yahoo提供的搜索引擎 在doPost 方法中 测试的是登陆的免费邮件系统 编译这个程序后 测试doGet 方法 可以用下面的命令行运行它 javaCGITestgetJava 产生的结果将保存在一个叫Get html的文件中 用浏览器打开它 可以看到同在上的搜索引擎中输入 Java 搜索产生的页面相同的效果 doGet 方法需要提供两个参数 第一个参数是创建交互的CGI程序的URL 第二个参数是一个List模板类 里面存放了提供的参数 要注意的是 把这些参数串在一起并接在URL的末尾时 必须用URLEncoder类的encode 方法对参数进行URL编码 如果要测试doPost 方法 须通过下面的命令行运行这个程序 javaCGITestpostUsernamePassword要测试登陆的免费邮箱 就必须在上注册一个邮箱 并在命令行的第2 3个参数提供登陆邮箱的用户名和密码 产生的结果保存在一个叫Post html的文件中 同样 浏览这个文件看到的同在网站上登录免费邮件系统所看到的页面一样 doPost 方法同样需要提供交互用的URL和保存参数的List 但是这里我们没有把参数串在一起 而是通过URLConnection类的getOutputStream 方法打开输入流 逐个将参数写入到输出流中 这样无论有多少参数也没关系了 但要注意的是 仍然要对参数进行URL编码并用 将它们分开 注 由于各网站的CGI程序URL和参数可能会随着网站的程序修改而改变 所以这个程序并不能保证一直得到正确的结果 但是只需查看网站的源代码 并找到HTMLForm的action以及input的所有参数 对上面例子中的程序略作修改 就可以顺利的得到正确结果了 11 2使用Socket通信 URL和URLConnection类提供给我们一种简便的方法编写网络程序 实现一些较高级的协议访问Internet 但是通常 这些协议是不够的 我们常需要用一种更通用 更底层的方法编写网络应用程序 这就是我们最常用的套接字 Socket 通信 11 2 1InetAddress类Internet上的每一台计算机都拥有一个惟一的地址 这样才能和其他网络上的计算机互通信息 我们常说的TCP IP中的IP InternetProtocal 就是定义Internet上计算机的地址的 我们知道 一个IP地址必须由四个0 255之间的数字组成 数字之间用点隔开 由于很难记忆这个由四个数字组成的地址 所以有了主机名 hostname 的出现 例如 就是一个主机名 InetAddress就是用来实现IP的类 InetAddress类的声名如下 publicfinalclassInetAddressextendsObjectimplementsSerializableInetAddress类没有提供任何构造函数 我们只能通过它本身提供的一些静态方法来建立一个它的实例 通常 用于建立一个InetAddress类的方法有如下几种 publicstaticInetAddressgetByName Stringhost throwsUnknowHostException指定主机名建立一个InetAddress的实例 publicstaticInetAddressgetByAddress byte addr throwsUnknowHostException指定IP地址建立一个InetAddress的实例 publicstaticInetAddressgetLocalHost throwsUnknowHostException建立本机的InetAddress的实例 下面我们通过一个实例来看看如何使用InetAddress类 例11 6InetAddressDemo javaimportgenesis publicclassInetAddressDemo publicstaticvoidmain String args try InetAddressaddr1 InetAddress getByName Transcript println addr1 getHostAddress InetAddressaddr2 InetAddress getByAddress addr1 getAddress Transcript println addr2 getHostName Transcript println InetAddressaddr3 InetAddress getLocalHost Transcript println addr3 getHostName Transcript println addr3 getHostAddress catch UnknownHostExceptione Transcript println e getMessage 程序的运行结果如图11 6所示 图11 6 从运行结果我们可以看到 调用getByName 方法通过主机名建立一个InetAddress类的实例后 我们就可以得到对应于这个主机名的地址 需要注意的是 在调用建立InetAddress实例的几个静态方法时 这些方法会连接指定的地址或域名 如果无法连通 会抛出一个UnknowHostException 所以必须用try catch块包含这个方法 并处理无法连通的情况 11 2 2客户端Socket类TCP IP最主要的功能是提供点对点通信机制 一个机器要在网络上与另一台机器通信 就需要建立一个互联的通道 这个通道传输两个数据流 一个为发出的数据流 一个为接收的数据流 由于有了IP地址 我们可以方便的在Internet上找到另一台机器 假如自己的机器要和另一台机器通信 就必须向那台主机发起一个连接请求 如果这个请求被接受 这次通信过程就开始了 通常情况下 我们把发起请求的机器叫客户端 被请求的机器则称为服务器 Socket类是用来编写客户端程序的类 Socket类的声明如下 publicclassSocketextendsObjectsSocket类常用的方法有下列几种 Socket InetAddressaddress intport throwsIOException建立一个Socket的实例 用来连接指定的地址和端口 Socket Stringhost intport throwsUnknowHostException IOException和上面类似 但是通过主机名代替InetAddress publicvoidclose throwsIOException中断该Socket连接 publicInetAddressgetInetAddress 返回该Socket实例所连接的地址 publicInputStreamgetInputStream throwsIOException返回一个输入流 用来接收服务器端发送的信息 publicOutputStreamgetOutputStream throwsIOException返回一个输出流 用来向服务器端发送信息 publicintgetPort 返回该Socket实例连接远程的端口 publicintgetSoTimeout throwsSocketException返回接收信息的时间限制 如果返回值为0 则表示没有限制 publicvoidsetSoTimeout inttimeout throwsSocketException 设置接收信息的时间限制 以千分之一秒为单位 利用InputStream接收信息时 程序会一直挂起 直到接收到信息 或者到达时间限制为止 如果出现超时 则会抛出一个java io InterruptedIOException 如果timeout设为0 则没有时间限制 程序会一直挂起等待 下面来看一个简单的Socket编程的示例 例11 7SocketDemo javaimportgenesis importjava io publicclassSocketDemo publicstaticvoidmain String args try 构造一个连接到时间服务器time A timefreq bldrdoc gov 端口13的Socket类实例 Socketsock newSocket time A timefreq bldrdoc gov 13 从Socket获得一个接收服务器信息的输入流BufferedReaderin newBufferedReader newInputStreamReader sock getInputStream while true Stringline in readLine if null line break else Transcript println line catch IOExceptione Transcript println e getMessage 程序的运行结果如图11 7所示 图11 7 这个例子非常简单 它打开了一个Socket类 这个Socket类连接到时间服务器time A timefreq bldrdoc gov的13端口上 当连接成功后 Socket类的getInputStream 方法返回一个InputStream对象 然后程序把流对象链接到一个BufferedReader上 接着就可以用readLine 方法读取服务器发送的所有字符 并把它们输出到屏幕上 直到readLine 方法返回null 即读完所有服务器发送的信息 程序才会结束 在Windows命令行下输入telnettime A timefreq bldrdoc gov13 可以看到和上面类似的输出结果 如图11 8所示 图11 8 11 2 3服务器端ServerSocket类前面实现了一个简单的网络客户程序 它可以从服务器上接收信息 下面我们学习实现服务器端的编程方法 一个服务器程序启动后 通常会监听某一个端口 等待某一台客户端计算机发出连接的请求 然后作出反应 ServerSocket类的声明如下 publicclassServerSocketextendsObjectsServerSocket类的大部分方法都和Socket类的类似 它最常用的构造方法如下 ServerSocket intport throwsIOException 创建一个ServerSocket示例是不需要指定IP地址的 SeverSocket总是处于监听本机端口的状态 下面我们看一个服务器程序的示例 例11 8ReversalServer javaimportjava io publicclassReversalServer publicstaticvoidmain String agrs try 创建一个监听8189端口的ServerSocketServerSockets newServerSocket 8189 启动ServerSocket的监听Socketinsock s accept 建立输入流通道BufferedReaderin newBufferedReader newInputStreamReader insock getInputStream 建立输出流通道PrintWriterout newPrintWriter insock getOutputStream true autoFlush out println Enterquittoexit while true Stringline in readLine if null line continue if line trim equals quit break else 翻转输入的字符串StringBufferrline newStringBuffer for inti line length i 0 i rline append line charAt i 1 out println Reversed rline toString out close in close insock close catch IOExceptione e printStackTrace 上面的例子是一个简单的服务器程序 它启动了一个ServerSocket监听本机的8189端口 这个端口一般不会被用到 当有其他客户端请求与它联接时 accept 方法将接受这个请求并创建一个独立的Socket实例 通过这个实例 我们可以取得输入和输出的两个流 程序首先通过输出流向客户端发送了一条问候信息 out println Hello Pleaseinput Enterquittoexit 然后 服务器程序接收来自客户端的输入 每次从客户端读取一行信息 就将这些输入的字符串翻转以后再送回给客户端 所以这个服务器程序叫做ReversalSever 编译并运行这个程序 然后在Windows命令行下输入 telnet127 0 0 18189 IP地址127 0 0 1是一个特殊的地址 称为本机回送地址 LocalLoopbackAddress 它代表着本机 由于运行服务器程序的机器和启动telnet测试的是同一主机 所以这个地址也正是我们要连接的 当然 也可以从其他机器上启动telnet来测试这个服务器程序 这时候就必须telnet到运行服务器程序的IP地址上 启动telnet以后 输入任何信息 看看结果是不是你想象的 最后输入quit结束连接 此处如输入 123456 则结果如图11 9所示 图11 9 11 2 4多客户通信机制我们注意到 前面例子中的服务器程序只能服务于一个客户端 也就是说 一个客户连接到这个服务程序后 将一直独占它 而通常情况下 我们看到的服务器总是要服务于许许多多的客户端的 比如一个网页服务器 可以接受许多客户的浏览 利用线程的特性 我们就可以很好地解决服务于多个客户的问题 我们只需要对上面的程序做少许修改 就可以使它服务于多个客户端 首先 应该把主程序部分放入一个循环 每接收到一个来自客户端的请求 就启动一个线程来处理他 而主程序则可以继续等待来自其他客户端的请求 下面看修改以后的程序 可试着启动多个telnet连接它进行测试 例11 9ThreadedReversalServer javaimportjava io publicclassThreadedReversalServer publicstaticvoidmain String agrs inti 0 try 创建一个监听8189端口的ServerSocketServerSockets newServerSocket 8189 for 启动ServerSocket的监听Socketinsock s accept System out println Thread i run 启动处理客户端信息的线程 newThreadReversal insock i start i catch IOExceptione e printStackTrace classThreadReversalextendsThread privateSocketsock privateintcounter publicThreadReversal Sockets inti sock s counter i publicvoidrun try 建立输入流通道BufferedReaderin newBufferedReader newInputStreamReader sock getInputStream 建立输出流通道PrintWriterout newPrintWriter sock getOutputStream true autoFlush out println Hello Pleaseinput Enterquittoexit while true Stringline in readLine if null line continue if line trim equals quit break else 翻转输入的字符串StringBufferrline newStringBuffer for inti line length i 0 i rline append line charAt i 1 out println Reversed rline toString out close in close sock close System out println Thread counter closed catch IOExceptione e printStackTrace 11 3使用UDP通信 前面一节我们学习了如何编写Socket的网络程序 即基于TCP TransmissionControlProtocol 传输控制协议 的网络编程 TCP只能创建两个计算机之间的可靠连接 一旦建立起一个TCP连接 我们就不需要处理传输可靠性的问题 可以认为通过Socket发送和接收数据的操作总是成功的 Java平台也支持所谓的UDP UserDatagramProtocol 用户数据报协议 UDP可以发送数据报 但它的开销比TCP少得多 UDP的缺陷是它不保证数据发送的可靠性 数据接收到的顺序可能和发送的顺序不同 甚至还可能完全丢失数据报 程序设计者必须负责整理和验证这些数据和请求重发 UDP特别适合容忍数据报部分丢失 而对实时性要求更高的应用程序 例如语音传输等 包提供了DatagrameSocket和DatagramPacket这两个类帮助我们实现基于UDP的网络程序设计 DatagramSocket用于收发数据报 而DatagramPacket包含发送的具体信息 数据报到达时 通过DatagramSocket 信息源的地址和端口将自动初始化 所以用于接收数据报的DatagramPacket构造方法为DatagramPacket byte buf intlength 而发出一个数据报时 DatagramPacket不仅需要包含数据内容 还要包含发送的地址以及端口 所以用于发送数据极的DatagramPacket构造方法为DatagramPacket byte buf intlength InetAddressaddress intport 下面我们看一个UDP编程的例子 例11 10服务器程序DayB importjava util publicclassDayBcast privateDatagramSocketds privateDatagramPacketdp privateInetAddressaddr publicstaticvoidmain String args throwsException DayBcastdb newDayBcast localhost db go publicDayBcast Stringtarget throwsException addr InetAddress getByName target ds newDatagramSocket publicvoidgo throwsException byte buff for Thread sleep 1000 System out println Sending Strings newDate toString buff s getBytes dp newDatagramPacket buff buff length addr 1313 ds send dp 客户端程序DayWatch java publicclassDayWatch privateDatagramSocketds privateDatagramPacketdp publicstaticvoidmain Stringargs throwsException DayWatchd newDayWatch d go publicvoidgo throwsException byte buff newbyte 64 Strings ds newDatagramSocket 1313 dp newDatagramPacket buff buff length for ds receive dp s newString dp getData System out println Timesignalreceivedform dp getAddress nTimeis s 先运行服务器程序 再运行客户端程序 客户端将以1s的间隔不断显示当前的时间 服务器的运行状态如图11 10所示 客户端的运行状态如图11 11所示 图11 10 图11 11
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 课件教案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!