第9章Socket网络编程SunnyLiuweiliu_china@163.com本课教学内容客户/服务器模型协议SocketSocket概况IP地址和端口创建Socket输入包创建服务器应用程序用于服务器的类和方法本课教学内容创建服务器监听客户请求启动服务器创建网络客户机所需的类和方法创建Socket类的对象从套接字读和写入套接字关闭连接问题陈述应用场景需要在Java中开发一个服务器应用程序,其功能说明如下:服务器应该能从客户机的Frame窗口接收用户登录信息。服务器应该能够将用户信息返回给客户。服务器应支持多线程,同时应该能为任何数量的客户机提供服务。服务器运行在端口#1432上。客户/服务器模型简介客户/服务器模型是一种内部数据处理和存储与数据显示相分离的应用程序开发结构。客户请求服务器而服务器完成这些请求。这些请求通过网络传到服务器。由于服务器所作的处理对客户是隐藏的。一个服务器可以服务多台客户机。客户/服务器模型通信原理客户机与服务器之间使用的大部分通信组件都是基于Socket接口来实现的Socket是两个程序之间进行双向数据传输的网络通信端点,由一个IP地址和一个端口号来标识每个服务器程序在提供服务时都要在一个端口进行,而想使用该服务的客户机也必须连接到该端口。客户/服务器模型客户机/服务器工作模式:创建服务器端Socket服务器端Socket登记某端口监听来自客户端的连接请求接收来自客户端的请求数据处理请求数据返回处理的数据给客户端创建客户端Socket通过服务器端的地址和端口向服务器端发送连接请求发送请求数据到服务器端接收响应数据服务器端客户端建立通信连接响应数据请求数据协议定义数据以包的形式从一台机器传到另一台机器。规则负责把打包数据放进包里,传送速度以及重建数据回到其原来形式。这些规则称为网络协议。协议TCP协议和UDP协议TCP是TranferControlProtocol的简称,是一种面向连接的保证可靠传输的协议。通过TCP协议传输,得到的是一个顺序的无差错的数据流。UDP是UserDatagramProtocol的简称,是一种无连接的协议,每个数据报都是一个独立的信息,包括完整的源地址或目的地址,它在网络上以任何可能的路径传往目的地,因此能否到达目的地,到达目的地的时间以及内容的正确性都是不能被保证的。SocketSocket概况Socket是基类,支持TCP协议。Socket类提供流I/O方法,使从Socket读出和写进方便。ServerSocket是由因特网服务器程序用于响应客户请求的类。ServerSocket实际上并不完成服务,而是为客户创建Socket对象。通信在创建的对象之间进行。SocketSocket类和ServerSocket类的构造方法:Socket(InetAddressaddress,intport);Socket(InetAddressaddress,intport,booleanstream);Socket(Stringhost,intprot);Socket(Stringhost,intprot,booleanstream);Socket(SocketImplimpl)Socket(Stringhost,intport,InetAddresslocalAddr,intlocalPort)Socket(InetAddressaddress,intport,InetAddresslocalAddr,intlocalPort)ServerSocket(intport);ServerSocket(intport,intbacklog);ServerSocket(intport,intbacklog,InetAddressbindAddr)SocketIP地址和端口TCP协议需要两个数据项:IP地址和端口号。每个协议都有缺省的端口号,如果端口号未指定,就使用它internet服务端口号端口号internet服务telnet23nntp119ftp21创建Socket下面是一个典型的创建客户端Socket的代码:try{Socketsocket=newSocket(127.0.0.1,1432);//127.0.0.1是TCP/IP协议中默认的本机地址}catch(IOExceptione){System.out.println(Error:+e);}Socket输入包使用import语句,为网络输入必要的包。例如:importjava.net.*;importjava.io.*;创建服务器应用程序用于服务器的类和方法要创建服务器,你需要创建ServerSocket对象监听客户请求的特定端口。当它认出有效请求,服务器Socket获得客户创建的Socket对象。用这Socket产生位于服务器和客户机之间的通信。创建服务器应用程序ServerSocket类ServerSocket类的构造函数带两个参数:第一个是端口号码;第二个参数表示可连接的最大数。ServerSocket类提供如下方法:监听连接返回地址和本机端口返回表示Socket的串创建服务器应用程序创建服务器构造函数的代码给出如下:try{server=newServerSocket(1432);//创建一个ServerSocket在端口1432监听客户请求}catch(Exceptione){System.out.println(cannotlistento:+e);//出错,打印出错信息}System.out.println(Serverstarted…);this.start();//启动线程创建服务器应用程序监听客户请求ServerSocket对象通过accept()方法来监听客户的请求,如果接收到客户的请求,则产生一个Socket对象,并继续执行后面的代码;如果没有接收到客户请求,则产生一个错误信息。创建服务器应用程序代码Socketsocket=null;try{socket=server.accept();//使用accept()阻塞等待客户请求,有客户//请求到来则产生一个Socket对象,并继续执行}catch(Exceptione){System.out.println(cannotlistento:+e);//出错,打印出错信息}创建服务器应用程序服务器的输入和输出流服务器端用到了以下的输入和输出流:BufferedReader对象用来表示从客户端输入到服务器的流PrintWriter对象表示服务器端输出到客户端的流BufferedReader对象表示从系统标准输入设备输入到服务器端的流。创建服务器应用程序代码如下:BufferedReaderis=newBufferedReader(newInputStreamReader(socket.getInputStream()));//由Socket对象得到输入流,并构造相应的BufferedReader对象PrintWriteros=newPrintWriter(socket.getOutputStream());//由Socket对象得到输出流,并构造PrintWriter对象BufferedReadersin=newBufferedReader(newInputStreamReader(System.in));//由系统标准输入设备构造BufferedReader对象{newServer();}创建服务器应用程序完整的服务器程序服务器程序创建了一个BufferedReader对象(is)和一个PrintStream对象(os)。is使用getInputStream()方法检索客户端的输入;os使用getOutputStream()方法使得服务器可以把输出写到客户端。这样一来,就开始了双向通信。当客户连接到服务器时,服务器在标准输出上打印从客户端读入的字符串,然后由BufferedReader对象sin的readline()方法从标准输入读入一字符串,并发送到客户端程序。当有一方输入”bye”时,通信结束。创建服务器应用程序到了结束的时候,服务器中断循环。关闭客户套接字。关闭套接字很重要,如果让连接开着,很快就将耗尽服务器的内存。创建服务器应用程序ObjectInputStream类ObjectInputStream类中包含从持久的存储介质中读出类的对象的功能。持久的存储介质可以是磁盘或套接字。这由ObjectInputStream类的readObject()方法来完成。readObject()方法的语法如下:FileInputStreamfp=newFileInputStream(“data.txt”);ObjectInputStreamistream=newObjectInputStream(fp);Datedate=(Date)istream.readObject();实例分析解题思路步骤1:选择创建网络服务器应用程序所需的类和方法。步骤2:确定用户定义的类,它们的目的,方法。步骤3:确定用户定义的类中的数据类型和变量。步骤4:确定服务器的IP地址和端口号。步骤5:确定查询参数。步骤6:确定要处理的异常。步骤7:确定异常的出错信息。任务求解步骤1:选择创建网络服务器应用程序所需的类和方法创建服务器应用程序需要用到:ServerSocket类的accept()方法;Thread类的start()和run()方法;Socket类的getInputStream()方法;以及ObjectInputStream类的readObject()方法。任务求解步骤2:确定用户定义的类,它们的目的,方法用户定义了FrameServer类,用于监听客户请求,包含run()方法;定义了Connection类,用于从客户端检索数据,包含Connection(),run()方法;定义了User类,用于保留登录信息。任务求解步骤3:确定用户定义的类中的数据类型和变量用户在FrameServer类中定义了serverSocket一个变量在Connection类中定义了netClient,fromClient,toClient三个变量在User类中定义了name,passwords两个变量。任务求解步骤4:确定服务器的IP地址和端口号服务器的IP地址是:127.0.0.1,端口是1432。步骤5:确定提交的参数提交的参数是:name,passwords任务求解步骤6:确定要处理的异常NotSerializableException异常当一个对象需要实现Serializable接口时,发生NotSerializableException异常。IOException异常IONotSerializableException异常意味着发生了某类输入/输出异常。所以当调用readObject()方法时,分别处理IOException异常,NotSerializableException异常。当创建Thread对象,调用accept()方法以及调用getInputStream()方法时,处理Exception异常。任务求解步骤7:确定异常的出错信息NotSerializableException异常的出错信息是:”读取对象出错”后跟异常对象。IOException(forthread)异常的出错信息是:”不能打开服务器。”后跟异常对象。IOException(foraccept())异常的出错信息是:”没有监听”后跟异常对象。IOException(forgetInputStream())异常的出错信息是:”不能建立双向流管道”后跟异常对象。任务求解编写服务器程序问题陈述应用场景需要修改UserFrame,使其连接到现有的网络服务器应