《java socket编程开发支持多并发的小型服务器.pdf》由会员分享,可在线阅读,更多相关《java socket编程开发支持多并发的小型服务器.pdf(35页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、http:/ 爱博文资料下载网 提供海量资料满足您的求知欲!欢迎常去光顾哦!本站所有资源部分转载自互联网!版权归作者所有!-java socketjava socket 编程编程开发支持开发支持多多并发的小型服务器并发的小型服务器 JavaSocket 套接字(socket)为两台计算机之间的通信提供了一种机制,在 JamesGosling 注意到Java 语言之前,套接字就早已赫赫有名。该语言只是让您不必了解底层操作系统的细节就能有效地使用套接字。1 客户机/服务器模型 在饭店里,菜单上各种具有异国情调的食品映入你的眼帘,于是你要了一份 pizza。几分钟后,你用力咀嚼浇着融化的乳酪和其他你
2、喜欢的配料的热 pizza。你不知道,也不想知道:侍者从那里弄来了 pizza,在制作过程中加进了什么,以及配料是如何获得的。上例中包含的实体有:美味的 pizza、接受你定餐的侍者、制作 pizza 的厨房,当然还有你。你是定 pizza 的顾客或客户。制作 pizza 的过程对于你而言是被封装的。你的请求在厨房中被处理,pizza 制作完成后,由侍者端给你。你所看到的就是一个客户机/服务器模型。客户机向服务器发送一个请求或命令。服务器处理客户机的请求。客户机和服务器之间的通讯是客户机/服务器模型中的一个重要组成部分,通常通过网络进行。客户机/服务器模型是一个应用程序开发框架,该框架是为了将
3、数据的表示与其内部的处理和存储分离开来而设计的。客户机请求服务,服务器为这些请求服务。请求通过网络从客户机传递到服务器。服务器所进行的处理对客户机而言是隐藏的。一个服务器可以为多台客户机服务。多台客户机访问服务器 服务器和客户机不一定是硬件组件。它们可以是工作啊同一机器或不同机器上的程序。、http:/ 爱博文资料下载网 提供海量资料满足您的求知欲!欢迎常去光顾哦!本站所有资源部分转载自互联网!版权归作者所有!-考虑一个航空定票系统中的数据输入程序:数据-乘客名、航班号、飞行日期、目的地等可以被输入到前端-客户机的应用程序中。一旦数据输入之后,客户机将数据发送到后端-服务器端。服务器处理数据并
4、在数据库中保存数据。客户机/服务器模型的重要性在于所有的数据都存放在同一地点。客户机从不同的地方访问同一数据源,服务器对所有的输入数据应用同样的检验规则。万维网为为什么要将数据的表示与其存储、处理分离开来提供了一个很好的例子。在Web 上,你无需控制最终用户用来访问你数据的平台和软件。你可以考虑编写出适用与每一种潜在的目标平台的应用程序。客户机/服务器应用程序的服务器部分管理通过多个客户机访问服务器的、多个用户共享的资源。表明客户机/服务器程序的服务器部分强大功能的最好例子应该是 Web 服务器,它通过 Internet 将 HTML 页传递给不同的 Web 用户。Java 编程语言中最基本的
5、特点是在 Java 中创建的程序的代码的可移植性。因为具有其他语言所不具备的代码可移植性,Java 允许用户只要编写一次应用程序,就可以在任何客户机系统上发布它,并可以让客户机系统解释该程序。这意味着:你只要写一次代码,就能使其在任何平台上运行。2 协议 当你同朋友交谈时,你们遵循一些暗含的规则(或协议)。例如:你们俩不能同时开始说话,或连续不间断地说话。如果你们这样作的话,谁也不能理解对方所说的东西。当你说话时,你的朋友倾听,反之亦然。你们以双方都能理解的语言和速度进行对话。当计算机之间进行通讯的时候,也需要遵循一定的规则。数据以包的形式从一台机器发送到另一台。这些规则管理数据打包、数据传输
6、速度和重新数据将其恢复成原始形式。这些规则被称为网络协议。网络协议是通过网络进行通讯的系统所遵循的一系列规则和惯例。连网软件通常实现有高低层次之分的多层协议。网络协议的例子有:TCP/IP、UDP、AppleTalk 和 NetBEUI。http:/ 爱博文资料下载网 提供海量资料满足您的求知欲!欢迎常去光顾哦!本站所有资源部分转载自互联网!版权归作者所有!-Java 提供了一个丰富的、支持网络的类库,这些类使得应用程序能方便地访问网络资源。Java 提供了两种通讯工具。它们是:使用用户报文协议(UDP)的报文和使用传输控制协议/因特网协议(TCP/IP)的 Sockets(套接字)。数据报包
7、是一个字节数组从一个程序(发送程序)传送到另一个(接受程序)。由于数据报遵守 UDP,不保证发出的数据包必须到达目的地。数据报并不是可信赖的。因此,仅当传送少量数据时才使用,而且发送者和接受者之间的距离间隔不大,假如是网络交通高峰,或接受程序正处理来自其他程序的多个请求,就有机会出现数据报包的丢失。Sockets 套接字用 TCP 来进行通讯。套接字模型同其他模型相比,优越性在于其不受客户请求来自何处的影响。只要客户机遵循 TCP/IP 协议,服务器就会对它的请求提供服务。这意味着客户机可以是任何类型的计算机。客户机不再局限为 UNIX、Windows、DOS 或Macintosh 平台,因此
8、,网上所有遵循 TCP/IP 协议的计算机可以通过套接字互相通讯。3 Sockets 套接字 3.1Sockets 概况 在客户机/服务器应用程序中,服务器提供象处理数据库查询或修改数据库中的数据之类的服务。发生在客户机和服务器之间的通讯必须是可靠的,同时数据在客户机上的次序应该和服务器发送出来的次序相同。什么是套接字?既然我们已经知道套接字扮演的角色,那么剩下的问题是:什么是套接字?BruceEckel 在他的Java 编程思想一书中这样描述套接字:套接字是一种软件抽象,用于表达两台机器之间的连接“终端”。对于一个给定的连接,每台机器上都有一个套接字,您也可以想http:/ 爱博文资料下载网
9、 提供海量资料满足您的求知欲!欢迎常去光顾哦!本站所有资源部分转载自互联网!版权归作者所有!-象它们之间有一条虚拟的“电缆”,“电缆”的每一端都插入到套接字中。当然,机器之间的物理硬件和电缆连接都是完全未知的。抽象的全部目的是使我们无须知道不必知道的细节。简言之,一台机器上的套接字与另一台机器上的套接字交谈就创建一条通信通道。程序员可以用该通道来在两台机器之间发送数据。当您发送数据时,TCP/IP 协议栈的每一层都会添加适当的报头信息来包装数据。这些报头帮助协议栈把您的数据送到目的地。好消息是Java 语言通过流为您的代码提供数据,从而隐藏了所有这些细节,这也是为什么它们有时候被叫做流套接字(
10、streamingsocket)的原因。把套接字想成两端电话上的听筒,我和您通过专用通道在我们的电话听筒上讲话和聆听。直到我们决定挂断电话,对话才会结束(除非我们在使用蜂窝电话)。而且我们各自的电话线路都占线,直到我们挂断电话。如果想在没有更高级机制如 ORB(以及 CORBA、RMI、IIOP 等等)开销的情况下进行两台计算机之间的通信,那么套接字就适合您。套接字的低级细节相当棘手。幸运的是,Java 平台给了您一些虽然简单但却强大的更高级抽象,使您可以容易地创建和使用套接字。传输控制协议(TCP)提供了一条可靠的、点对点的通讯通道,客户机/服务器应用程序可以用该通道互相通讯。要通过 TCP
11、 进行通讯,客户机和服务器程序建立连接并绑定套接字。套接字用于处理通过网络连接的应用程序之间的通讯。客户机和服务器之间更深入的通讯通过套接字完成。Java 被设计成一种连网语言。它通过将连接功能封装到套接字类里而使得网络编程更加容易。套接字类即 Socket 类(它创建一个客户套接字)和 ServerSocket 类(它创建一个服务器套接字)。套接字类大致介绍如下:l Socket 是基类,它支持 TCP 协议。TCP 是一个可靠的流网络连接协议。Socket 类提供了流输入/输出的方法,使得从套接字中读出数据和往套接字中写数据都很容易。该类对于编写因特网上的通讯程序而言是必不可少的。http
12、:/ 爱博文资料下载网 提供海量资料满足您的求知欲!欢迎常去光顾哦!本站所有资源部分转载自互联网!版权归作者所有!-l ServerSocket 是一个因特网服务程序用来监听客户请求的类。ServerSocket 实际上并不执行服务;而是创建了一个 Socket 对象来代表客户机。通讯由创建的对象来完成。3.2IP 地址和端口 因特网服务器可以被认为是一组套接字类,它们提供了一般称为服务的附加功能。服务的例子有:电子邮件、远程登录的 Telnet、和通过网络传输文件的文件传输协议(FTP)。每种服务都与一个端口相联系。端口是一个数值地址,通过它来处理服务请求(就象请求Web 页一样)。TCP
13、协议需要两个数据项:IP 地址和端口号。因此,当键入 http:/ 时,你是如何进入金诺的主页呢?因特网协议(IP)提供每一项网络设备。这些设备都带有一个称为 IP 地址的逻辑地址。由因特网协议提供的 IP 地址具有特定的形式。每个 IP 地址都是 32 位的数值,表示 4 个范围在 0 到 255 之间的 8 位数值金诺已经注册了它的名字,分配给 http:/ 的IP 地址为 192.168.0.110。注意:域名服务或 DNS 服务是将 http:/ 翻译成 192.168.0.110 的服务。这使你可以键入 http:/ 而不必记住 IP 地址。想象一下,怎么可能记住所有需要访问的站点的
14、 IP 地址!有趣的是一个网络名可以映射到许多 IP 地址。对于经常访问的站点可能需要这一功能,因为这些站点容纳大量的信息,并需要多个 IP 地址来提供业务服务。例如:192.168.0.110 的实际的内部名称为 http:/。DNS 可以将分配给 jinnuoLtd.的一系列 IP 地址翻译成 http:/。如果没有指明端口号,则使用服务文件中服务器的端口。每种协议有一个缺省的端口号,在端口号未指明时使用该缺省端口号。端口号 应用 21 FTP.传输文件 23 Telnet.提供远程登录 http:/ 爱博文资料下载网 提供海量资料满足您的求知欲!欢迎常去光顾哦!本站所有资源部分转载自互联
15、网!版权归作者所有!-25 SMTP.传递邮件信息 67 BOOTP.在启动时提供配置情况 80 HTTP.传输 Web 页 109 POP.使用户能访问远程系统中的邮箱 让我们再来看一下 URl:http:/ URL 的第一部分(http)意味着你正在使用超文本传输协议(HTTP),该协议处理 Web 文档。如果没有指明文件,大多数的 Web 服务器会取一个叫 index.html 文件。因此,IP 地址和端口既可以通过明确指出 URL 各部分来决定,也可以由缺省值决定。4 创建 Socket 客户 我们将在本部分讨论的示例将阐明在 Java 代码中如何使用 Socket 和 ServerS
16、ocket。客户机用 Socket 连接到服务器。服务器用 ServerSocket 在端口 1001 侦听。客户机请求服务器C:驱动器上的文件内容。创建 RemoteFileClient 类 importjava.io.*;.*;publicclassRemoteFileClient protectedBufferedReadersocketReader;protectedPrintWritersocketWriter;protectedStringhostIp;protectedinthostPort;/构造方法 publicRemoteFileClient(StringhostIp,in
17、thostPort)http:/ 爱博文资料下载网 提供海量资料满足您的求知欲!欢迎常去光顾哦!本站所有资源部分转载自互联网!版权归作者所有!-this.hostIp=hostIp;this.hostPort=hostPort;/向服务器请求文件的内容 publicStringgetFile(StringfileNameToGet)StringBufferfileLines=newStringBuffer();try socketWriter.println(fileNameToGet);socketWriter.flush();Stringline=null;while(line=socke
18、tReader.readLine()!=null)fileLines.append(line+);catch(IOExceptione)System.out.println(Errorreadingfromfile:+fileNameToGet);returnfileLines.toString();/连接到远程服务器 publicvoidsetUpConnection()try Socketclient=newSocket(hostIp,hostPort);socketReader=newBufferedReader(newInputStreamReader(client.getInputS
19、tream();socketWriter=newPrintWriter(client.getOutputStream();catch(UnknownHostExceptione)http:/ 爱博文资料下载网 提供海量资料满足您的求知欲!欢迎常去光顾哦!本站所有资源部分转载自互联网!版权归作者所有!-System.out.println(Error1settingupsocketconnection:unknownhostat+hostIp+:+hostPort);catch(IOExceptione)System.out.println(Error2settingupsocketconnec
20、tion:+e);/断开远程服务器 publicvoidtearDownConnection()try socketWriter.close();socketReader.close();catch(IOExceptione)System.out.println(Errortearingdownsocketconnection:+e);publicstaticvoidmain(Stringargs)RemoteFileClientremoteFileClient=newRemoteFileClient(127.0.0.1,1001);remoteFileClient.setUpConnecti
21、on();StringBufferfileContents=newStringBuffer();fileContents.append(remoteFileClient.getFile(RemoteFileServer.java);/remoteFileClient.tearDownConnection();System.out.println(fileContents);http:/ 爱博文资料下载网 提供海量资料满足您的求知欲!欢迎常去光顾哦!本站所有资源部分转载自互联网!版权归作者所有!-首先我们导入 和 java.io。 包为您提供您需要的套接字工具。java.io包为您提供对流进行读
22、写的工具,这是您与 TCP 套接字通信的唯一途径。我们给我们的类实例变量以支持对套接字流的读写和存储我们将连接到的远程主机的详细信息。我们类的构造器有两个参数:远程主机的 IP 地址和端口号各一个,而且构造器将它们赋给实例变量。我们的类有一个 main()方法和三个其它方法。稍后我们将探究这些方法的细节。现在您只需知道 setUpConnection()将连接到远程服务器,getFile()将向远程服务器请求fileNameToGet 的内容以及 tearDownConnection()将从远程服务器上断开。实现 main()这里我们实现 main()方法,它将创建 RemoteFileCli
23、ent 并用它来获取远程文件的内容,然后打印结果。main()方法用主机的 IP 地址和端口号实例化一个新 RemoteFileClient(客户机)。然后,我们告诉客户机建立一个到主机的连接。接着,我们告诉客户机获取主机上一个指定文件的内容。最后,我们告诉客户机断开它到主机的连接。我们把文件内容打印到控制台,只是为了证明一切都是按计划进行的。建立连接 这里我们实现 setUpConnection()方法,它将创建我们的 Socket 并让我们访问该套接字的流:publicvoidsetUpConnection()try Socketclient=newSocket(hostIp,hostPo
24、rt);socketReader=newBufferedReader(newInputStreamReader(client.getInputSthttp:/ 爱博文资料下载网 提供海量资料满足您的求知欲!欢迎常去光顾哦!本站所有资源部分转载自互联网!版权归作者所有!-ream();socketWriter=newPrintWriter(client.getOutputStream();catch(UnknownHostExceptione)System.out.println(Error1settingupsocketconnection:unknownhostat+hostIp+:+hos
25、tPort);catch(IOExceptione)System.out.println(Error2settingupsocketconnection:+e);setUpConnection()方法用主机的 IP 地址和端口号创建一个 Socket:Socketclient=newSocket(hostIp,hostPort);我们把 Socket 的 InputStream 包装进 BufferedReader 以使我们能够读取流的行。然后,我们把 Socket 的 OutputStream 包装进 PrintWriter 以使我们能够发送文件请求到服务器:socketReader=new
26、BufferedReader(newInputStreamReader(client.getInputStream();socketWriter=newPrintWriter(client.getOutputStream();请记住我们的客户机和服务器只是来回传送字节。客户机和服务器都必须知道另一方即将发送的是什么以使它们能够作出适当的响应。在这个案例中,服务器知道我们将发送一条有效的文件路径。当您实例化一个 Socket 时,将抛出 UnknownHostException。这里我们不特别处理它,但我们打印一些信息到控制台以告诉我们发生了什么错误。同样地,当我们试图获取 Socket的 In
27、putStream 或 OutputStream 时,如果抛出了一个一般 IOException,我们也打印一些信息到控制台。http:/ 爱博文资料下载网 提供海量资料满足您的求知欲!欢迎常去光顾哦!本站所有资源部分转载自互联网!版权归作者所有!-与主机交谈 这里我们实现 getFile()方法,它将告诉服务器我们想要什么文件并在服务器传回其内容时接收该内容。publicStringgetFile(StringfileNameToGet)StringBufferfileLines=newStringBuffer();try socketWriter.println(fileNameToGet
28、);socketWriter.flush();Stringline=null;while(line=socketReader.readLine()!=null)fileLines.append(line+);catch(IOExceptione)System.out.println(Errorreadingfromfile:+fileNameToGet);returnfileLines.toString();对 getFile()方法的调用要求一个有效的文件路径 String。它首先创建名为 fileLines 的StringBuffer,fileLines 用于存储我们读自服务器上的文件的每
29、一行。StringBufferfileLines=newStringBuffer();在 trycatch块中,我们用 PrintWriter 把请求发送到主机,PrintWriter 是我们在创建连接期间建立的。socketWriter.println(fileNameToGet);socketWriter.flush();请注意这里我们是 flush()该 PrintWriter,而不是关闭它。这迫使数据被发送到服务器而不关闭 Socket。http:/ 爱博文资料下载网 提供海量资料满足您的求知欲!欢迎常去光顾哦!本站所有资源部分转载自互联网!版权归作者所有!-一旦我们已经写到 Sock
30、et,我们就希望有一些响应。我们不得不在 Socket 的 InputStream上等待它,我们通过在 while 循环中调用 BufferedReader 上的 readLine()来达到这个目的。我们把每一个返回行附加到 fileLinesStringBuffer(带有一个换行符以保护行):Stringline=null;while(line=socketReader.readLine()!=null)fileLines.append(line+);断开连接 这里我们实现 tearDownConnection()方法,它将在我们使用完毕连接后负责“清除”。tearDownConnectio
31、n()方法只是分别关闭我们在 Socket 的 InputStream 和 OutputStream上创建的 BufferedReader 和 PrintWriter。这样做会关闭我们从 Socket 获取的底层流,所以我们必须捕捉可能的 IOException。用 java socket 开发支持上千个并发的小型服务器 时间:2010-04-15 总结一下客户机 我们的类研究完了。在我们继续往前讨论服务器端的情况之前,让我们回顾一下创建和使用 Socket 的步骤:1.用您想连接的机器的 IP 地址和端口实例化 Socket(如有问题则抛出 Exception)。2.获取 Socket 上的
32、流以进行读写。3.把流包装进 BufferedReader/PrintWriter 的实例,如果这样做能使事情更简单的话。4.对 Socket 进行读写。http:/ 爱博文资料下载网 提供海量资料满足您的求知欲!欢迎常去光顾哦!本站所有资源部分转载自互联网!版权归作者所有!-5.关闭打开的流。5 创建服务器 Socket 创建 RemoteFileServer 类 importjava.io.*;.*;publicclassRemoteFileServer intlistenPort;publicRemoteFileServer(intlistenPort)this.listenPort=l
33、istenPort;/允许客户机连接到服务器,等待客户机请求 publicvoidacceptConnections()try ServerSocketserver=newServerSocket(listenPort);SocketincomingConnection=null;while(true)incomingConnection=server.accept();handleConnection(incomingConnection);catch(BindExceptione)System.out.println(Unabletobindtoport+listenPort);catch
34、(IOExceptione)System.out.println(UnabletoinstantiateaServerSocketonport:+listenPort);http:/ 爱博文资料下载网 提供海量资料满足您的求知欲!欢迎常去光顾哦!本站所有资源部分转载自互联网!版权归作者所有!-/与客户机 Socket 交互以将客户机所请求的文件的内容发送到客户机 publicvoidhandleConnection(SocketincomingConnection)try OutputStreamoutputToSocket=incomingConnection.getOutputStream
35、();InputStreaminputFromSocket=incomingConnection.getInputStream();BufferedReaderstreamReader=newBufferedReader(newInputStreamReader(inputFromSocket);FileReaderfileReader=newFileReader(newFile(streamReader.readLine();BufferedReaderbufferedFileReader=newBufferedReader(fileReader);PrintWriterstreamWrit
36、er=newPrintWriter(incomingConnection.getOutputStream();Stringline=null;while(line=bufferedFileReader.readLine()!=null)streamWriter.println(line);fileReader.close();streamWriter.close();streamReader.close();catch(Exceptione)System.out.println(Errorhandlingaclient:+e);http:/ 爱博文资料下载网 提供海量资料满足您的求知欲!欢迎常
37、去光顾哦!本站所有资源部分转载自互联网!版权归作者所有!-e.printStackTrace();publicstaticvoidmain(Stringargs)RemoteFileServerserver=newRemoteFileServer(1001);server.acceptConnections();1(未取到网页内容)跟客户机中一样,我们首先导入 的 java.io。接着,我们给我们的类一个实例变量以保存端口,我们从该端口侦听进入的连接。缺省情况下,端口是 1001。我们的类有一个 main()方法和两个其它方法。稍后我们将探究这些方法的细节。现在您只需知道 acceptConn
38、ections()将允许客户机连接到服务器以及 handleConnection()与客户机 Socket 交互以将您所请求的文件的内容发送到客户机。实现 main()这里我们实现 main()方法,它将创建 RemoteFileServer 并告诉它接受连接:服务器端的main()方法中,我们实例化一个新 RemoteFileServer,它将在侦听端口(1001)上侦听进入的连接请求。然后我们调用 acceptConnections()来告诉该 server 进行侦听。接受连接 http:/ 爱博文资料下载网 提供海量资料满足您的求知欲!欢迎常去光顾哦!本站所有资源部分转载自互联网!版权归
39、作者所有!-这里我们实现 acceptConnections()方法,它将创建一个 ServerSocket 并等待连接请求:publicvoidacceptConnections()try ServerSocketserver=newServerSocket(listenPort);SocketincomingConnection=null;while(true)incomingConnection=server.accept();handleConnection(incomingConnection);catch(BindExceptione)System.out.println(Unab
40、letobindtoport+listenPort);catch(IOExceptione)System.out.println(UnabletoinstantiateaServerSocketonport:+listenPort);acceptConnections()用欲侦听的端口号来创建 ServerSocket。然后我们通过调用该ServerSocket 的 accept()来告诉它开始侦听。accept()方法将造成阻塞直到来了一个连接请求。此时,accept()返回一个新的 Socket,这个 Socket 绑定到服务器上一个随机指定的端口,返回的 Socket 被传递给 hand
41、leConnection()。请注意我们在一个无限循环中处理对连接的接受。这里不支持任何关机。无论何时如果您创建了一个无法绑定到指定端口(可能是因为别的什么控制了该端口)的ServerSocket,Java 代码都将抛出一个错误。所以这里我们必须捕捉可能的BindException。就跟在客户机端上时一样,我们必须捕捉 IOException,当我们试图在http:/ 爱博文资料下载网 提供海量资料满足您的求知欲!欢迎常去光顾哦!本站所有资源部分转载自互联网!版权归作者所有!-ServerSocket 上接受连接时,它就会被抛出。请注意,您可以通过用毫秒数调用setSoTimeout()来为
42、accept()调用设置超时,以避免实际长时间的等待。调用setSoTimeout()将使 accept()经过指定占用时间后抛出 IOException。处理连接 这里我们实现 handleConnection()方法,它将用连接的流来接收输入和写输出:publicvoidhandleConnection(SocketincomingConnection)try OutputStreamoutputToSocket=incomingConnection.getOutputStream();InputStreaminputFromSocket=incomingConnection.getInp
43、utStream();BufferedReaderstreamReader=newBufferedReader(newInputStreamReader(inputFromSocket);FileReaderfileReader=newFileReader(newFile(streamReader.readLine();BufferedReaderbufferedFileReader=newBufferedReader(fileReader);PrintWriterstreamWriter=newPrintWriter(incomingConnection.getOutputStream();
44、Stringline=null;while(line=bufferedFileReader.readLine()!=null)streamWriter.println(line);fileReader.close();streamWriter.close();streamReader.close();http:/ 爱博文资料下载网 提供海量资料满足您的求知欲!欢迎常去光顾哦!本站所有资源部分转载自互联网!版权归作者所有!-catch(Exceptione)System.out.println(Errorhandlingaclient:+e);e.printStackTrace();跟在客户机中
45、一样,我们用 getOutputStream()和 getInputStream()来获取与我们刚创建的 Socket 相关联的流。跟在客户机端一样,我们把 InputStream 包装进BufferedReader,把 OutputStream 包装进 PrintWriter。在服务器端上,我们需要添加一些代码,用来读取目标文件和把内容逐行发送到客户机。这里是重要的代码:FileReaderfileReader=newFileReader(newFile(streamReader.readLine();BufferedReaderbufferedFileReader=newBufferedR
46、eader(fileReader);Stringline=null;while(line=bufferedFileReader.readLine()!=null)streamWriter.println(line);这些代码值得详细解释。让我们一点一点来看:FileReaderfileReader=newFileReader(newFile(streamReader.readLine();首先,我们使用 Socket 的 InputStream 的 BufferedReader。我们应该获取一条有效的文件路径,所以我们用该路径名构造一个新 File。我们创建一个新 FileReader 来处理
47、读文件的操作。BufferedReaderbufferedFileReader=newBufferedReader(fileReader);这里我们把 FileReader 包装进 BufferedReader 以使我们能够逐行地读该文件。http:/ 爱博文资料下载网 提供海量资料满足您的求知欲!欢迎常去光顾哦!本站所有资源部分转载自互联网!版权归作者所有!-接着,我们调用 BufferedReader 的 readLine()。这个调用将造成阻塞直到有字节到来。我们获取一些字节之后就把它们放到本地的 line 变量中,然后再写出到客户机上。完成读写操作之后,我们就关闭打开的流。请注意我们在
48、完成从 Socket 的读操作之后关闭 streamWriter 和 streamReader。您或许会问我们为什么不在读取文件名之后立刻关闭 streamReader。原因是当您这样做时,您的客户机将不会获取任何数据。如果您在关闭 streamWriter 之前关闭 streamReader,则您可以往 Socket 写任何东西,但却没有任何数据能通过通道(通道被关闭了)。总结一下服务器 在我们接着讨论另一个更实际的示例之前,让我们回顾一下创建和使用 ServerSocket 的步骤:1.用一个您想让它侦听传入客户机连接的端口来实例化一个 ServerSocket(如有问题则抛出 Excep
49、tion)。2.调用 ServerSocket 的 accept()以在等待连接期间造成阻塞。3.获取位于该底层 Socket 的流以进行读写操作。4.按使事情简单化的原则包装流。5.对 Socket 进行读写。6.关闭打开的流(并请记住,永远不要在关闭 Writer 之前关闭 Reader)。6 创建多线程 Socket 服务器 前面的示例教给您基础知识,但并不能令您更深入。如果您到此就停止了,那么您一次只能处理一台客户机。原因是 handleConnection()是一个阻塞方法。只有当它完成了对当前http:/ 爱博文资料下载网 提供海量资料满足您的求知欲!欢迎常去光顾哦!本站所有资源部
50、分转载自互联网!版权归作者所有!-连接的处理时,服务器才能接受另一个客户机。在多数时候,您将需要(也有必要)一个多线程服务器。创建 MultithreadedRemoteFileServer 类 importjava.io.*;.*;publicclassMultithreadedRemoteFileServer intlistenPort;publicMultithreadedRemoteFileServer(intlistenPort)this.listenPort=listenPort;/允许客户机连接到服务器,等待客户机请求 publicvoidacceptConnections()t