• 1. Java网络编程 第8章
  • 2. 8.1 引言和本章任务 理解网络的基本概念; 掌握URL类、URLconnection类、InetAddress类的用法; 理解什么是流套接字,并利用Socket类和ServerSocket类实现流套接字编程; 理解什么是数据报套接字,并利用Java语言提供的UDP编程机制实现数据报套接字编程。2
  • 3. 8.2 基础知识链接3
  • 4. 8.2.1 Java与网络Java语言取得成功的领域之一就是网络 (其他语言)数页代码---->(Java)一条语句 TCP/IP(传输控制协议/网间协议)是internet的主要协议,定义了计算机和外设进行通信所使用的规则(应用层,传输层,网络层,链路层). 大多数基于internet的应用程序被看作TCP/IP协议的上一层. 如 : ftp, http, smtp, pop3, telnet, nntp等 IP地址:TCP/IP网络中的每台计算机都有唯一的地址--IP地址. 在Java中,有一个用来存储internet地址的类叫InetAddress.4
  • 5. Java与网络例:获取本机的IP地址 import java.net.*; public class getLocalHostTest { public static void main() { InetAddress myIP=null; try {myIP=InetAddress.getLocalHost();} catch{UnknowHostException e){} System.out.println(myIP); } } 创建inetAddress类不用构造函数(不用new)5
  • 6. Java与网络下面的例子演示java如何根据域名自动到DNS 上查找IP地址(与DNS服务器的连接减至一行) import java.net.*; public class getIP { public static void main(String args[]) { InetAddress pku=null; try{ pku= InetAddress.getByName(“www.pku.edu.cn”); }catch(UnknowHostException e) {} System.out.println(pku); } }6
  • 7. Java与网络Java提供的网络功能有三大类: URL, Socket, Datagram. URL是三大功能中最高级的一种,通过URL Java程序可以直接送出或读入网络上的数据. Socket是传统网络程序最常用的方式,可以想象为两个不同的程序通过网络的通信信道. Datagram是更低级的网络传输方式,它把数据的目的纪录在数据包中,然后直接放在网络上.7
  • 8. 8.2.2 Java基本的网络功能URL类及其使用 URL连接(URLconnection类) InetAddress类8
  • 9. URL类及其使用 通过URL读取WWW服务器上的数据 将URL位置的数据转成一个数据流 URL url=new (http://www.google.com” DataInputStream data=new DataInputStream(url.openStream()); 从数据流中读出数据 String line=data.readLine() while(line!=null) line=data.readLine() 9
  • 10. URL连接(URLconnection类)3-1URL双向通信(URLConection) URLConnection是一个一http为中心的类 1. 建立连接 URL url=new URL(“http://www.yahoo.com/”); URLConnection con=url.openConnection(); 2. 向服务器端送数据 PrintStream outStream=new PrintStream(con.getOutputStream()); outStream.println(string_data); 10
  • 11. URL连接(URLconnection类)3-23. 从服务器读数据 DataInputStream inStream=new DataInputStream(con.getInputStream()); inStream.readLine(); 从URL中得到的输出流通常与一个CGI程序结合一起工作客户端 java程序DataOutputStreamDataInputStreamCGI程序 STDINSTDOUT服务器 ( 排序 sort.cgi)connectiuongetchar()putchar()11
  • 12. URL连接(URLconnection类)3-3URLConnection同时支持get和post两种机制一般的格式. 缺省情况下位post method方式 URL和URLConnection的区别在于前者代表一个资源的位置,后者代表一种连接12
  • 13. InetAddress类使用起来较简单,具体使用见本书介绍13
  • 14. 8.2.3 Java套接字编程 什么是套接字 基于TCP的通信 基于UDP的通信14
  • 15. 什么是套接字(Socket)2-1Socket是网络上运行的程序之间双向通信链路的最后终结点网络服务Mailftpfinger20telnet数据结构I/O缓冲区端口2123客户程序SocketIP,portIP与端口的组合得出一个套接字,可以完全分辨internet上运行的程序15
  • 16. 什么是套接字(Socket)2-2internet服务端口号端口号internet服务telnet 23 nntp 119ftp 21 www 80DNS 53 POP3 110端口号:TCP/IP协议为每种服务定义了一个端口,当一台计算机上运行不同服务器程序时,,根据端口号不同提供相应的服务. 端口号不是计算机上的物理连接器,它只是具有软件意义的假想端口16
  • 17. 基于TCP的通信21-1在服务器端通过指定一个用来等待的连接的端口号创建一个 ServerSocket实例. 在客户端通过规定一个主机和端口号创建一个 socket实例,连到服务器上. ServerSocket类的accept方法使服务器处于阻塞状态,等待用户请求 Socket类和ServerSocket是基于TCP协议的,TCP协议提供64个端口,256以内位保留端口.17
  • 18. 基于TCP的通信21-2在本地机器上测试网络程序用回送地址Socket socket=new Socket(“127.0.0.1”,2525); 如果网络的一端已经关闭,另一端读到null. 建立socket连接后,还应该建立输入输出数据流.18
  • 19. 基于TCP的通信21-3ServerServerSocket(port #)Server Socket.accept()Socket()OutputStreamInputStreamClose SocketClientSocket(host, port #)Attempt the connectionOutputStreamInputStreamClose Socket19
  • 20. 基于TCP的通信21-4下面的例子演示一个简单的服务器与客户的交互,即服务器等待,客户访问,相互通一次信息. 20
  • 21. 基于TCP的通信21-5. 8.5 Socket创建服务器(端口号)定义数据成员服务器等待 网络连接建立socket流读客户 端信息向用户发出一个字符串创建Socket实例定义数据成员建立socket流读socket流 (接收并显示)送用户名给 服务器关闭流waiting for user127.0.0.1 11111111login:connetcting client...java提示用户登录成功读socket流User :javaLogin successful21
  • 22. 基于TCP的通信21-6例:显示服务器与客户机间的通信(服务器端)PrintStream ps=null; DataInputStream dis=null; String username; ServerSocket serverSocket=null; Socket clientSocket=null;try { serverSocket=new ServerSocket(1111); }catch (IOException e) { System.out.println( “Error”+e); System.exit(1);}try { clientSocket=serverSocket.accept(); }catch (IOException e){ System.out.println("Accept failed.");System.exit(1);}创建服务器(端口号)定义数据成员服务器等待 网络连接22
  • 23. 基于TCP的通信21-7.ps=new PrintStream(clientSocket.getOutputStream()); dis=new DataInputStream(clientSocket.getInputStream()); 创建服务器(端口号)定义数据成员服务器等待 网络连接建立socket流向客户发出登录要求 ps.println("login:"); ps.flush();23
  • 24. 基于TCP的通信21-8ps.println("login sucessful"); ps.flush(); System.out.println(username+" has logged off");}读客户 端信息创建服务器(端口号)定义数据成员服务器等待 网络连接建立socket流向用户发出登录要求通知客户连接完毕if ((username=dis.readLine())==null) { System.out.println("readLine returned null"); System.exit(1); } System.out.println("Username:"+username);24
  • 25. 基于TCP的通信21-9例:显示服务器与客户机间的通信(客户端)创建Socket实例PrintStream output; DataInputStream input; String string; Socket socket=null;定义数据成员try{socket=new Socket("127.0.0.1",1111); }catch(IOException e){ System.out.println("Error ”+e); return;} input=new DataInputStream(socket.getInputStream()); output=new PrintStream(socket.getOutputStream()); 建立socket流25
  • 26. 基于TCP的通信21-10.System.out.println(input.readLine());创建Socket实例定义数据成员建立socket流读socket流 (看到提示)System.in.read(bArray); String s=new String(bArray,0); output.println(s);从键盘上读送用户 名送给服务器端关闭流socket.close(); input.close(); output.close(); System.out.println("Done");System.out.println(input.readLine()); System.out.print("Logging off...");读服务器反馈26
  • 27. 基于TCP的通信21-11. 8.5 Socket创建服务器(端口号)定义数据成员服务器等待 网络连接建立socket流读客户 端信息向用户发送字符串创建Socket实例定义数据成员建立socket流读socket流 (看到提示)送用户名给 服务器关闭流waiting for user127.0.0.1 11111111login:connetcting client...java提示用户登录成功读socket流User :javaLogin successful27
  • 28. 基于TCP的通信21-12支持多客户 一种解决方案: 一台计算机上一次启动多个服务器程序,只要端口号不同.\myjava\clientAndServerTest myserver <-------->myclient----f8.bat myserver2<-------->myclient2----f9.batServer1(1111)client(2222)Server2(2222)client(1111)Computer 128
  • 29. 基于TCP的通信21-13第二种方案: (支持多客户) Server client1client2serverthreadserverthread将服务器写成多线程的,不同的线程为不同的客户服务. main()只负责循环等待 线程负责网络连接,接收客户输入的信息29
  • 30. 基于TCP的通信21-14.客户1客户2服务器线程()线程2线程( )线程( )30
  • 31. . 8.5 Socket创建服务器(端口号)定义数据成员服务器等待 网络连接建立socket流读客户 端信息提示用户输入客户名创建Socket实例定义数据成员建立socket流读socket流 (看到提示)送用户名给 服务器关闭流waiting for user127.0.0.1 11111111login:connetcting client...java提示用户登录成功读socket流User :javaLogin successful31
  • 32. 基于TCP的通信21-16public static void main(String args[]) {ServerSocket serverSocket=null; try{serverSocket=new ServerSocket(1111); }catch(Exception e){ System.out.println(”Error”+e);System.exit(1);} while(true) {Socket clientSocket=null; System.out.println("waiting for users..."); try { clientSocket=serverSocket.accept(); }catch(IOException e){ System.out.println("accept failed:"+e);} new serverThread(clientSocket).start(); }}32
  • 33. 基于TCP的通信21-17class serverThread extends Thread { DataInputStream input; PrintStream output; String user; Socket clientSocket; serverThread(Socket clientSocket) { this.clientSocket=clientSocket; } public void run() { try{ input=new DataInputStream (clientSocket.getInputStream()); output=System.out; user=input.readLine(); System.out.println(user+" Connected!"); }catch(IOException e){ } try {while(true) { String string; if((string=input.readLine())==null) break; output.println(user+string); output.flush(); } }catch(Exception e){ return; } System.out.println(user+ "has disconnected."); try{ clientSocket.close(); input.close(); }catch(Exception e){ return; } }}33
  • 34. serverHello 1076Hello 1071abcWAIT GO…abcWAIT GO…defdef 基于TCP的通信21-18例:通过服务器交换信息(exchangebyserver)34
  • 35. 基于TCP的通信21-19.服务器 (1111) accept socket 客 户IP client1线程客 户IP client2线程服务器一端为了能接收多个客户的信息,它的输入流,输出流都是数组型的. ServerSocket.accept()等待用户连接,一旦连接上,则调用服务程序. 服务程序的主要内容是网络的读写,多客户的原因,网络读写的功能用多线程实现,因此将此部分功能单独分离出来,构成线程类 35
  • 36. 基于TCP的通信21-20client1client2serviceRequestserverServerSocketSocketgetOutputStreamgetInputStreamreader.runreader.run服务器端accept()reader.start()read_net_inputwrite_net_output()36
  • 37. client()write.runwrite_net_output()read_net_input()close_server()客户端writer.start()paint()socketgetLocalPort()getInputStreamgetOutputStream服 务 器基于TCP的通信21-2137
  • 38. 基于UDP的通信9-1TCP/IP传输层由两个并列的协议:TCP,UDP. 一般套接字(TCP)提供一个可靠的传输模型作为两个网络端点的字节流,有纠错能力. UDP没有保持的连接和数据流,数据报是一个网络上发送的独立信息,它的到达,到达时间,以及内容不能得到保证.socketserverclientdatagramserverclient38
  • 39. 基于UDP的通信9-2TCP提供高可靠性服务,适用于一次要传输交换大量报文的情况,信道上传递的包不需要源地址和目的地址 UDP提供高效率服务,适用于依次传输交换少量报文的情形 (如数据库查询),每个数据包要包含目的地址和端口号. 数据报文的使用以包为中心:打包,拆包. Java.net包支持两种不同的在网络上送数据的方法:一般套接字和数据报文套接字. 39
  • 40. 基于UDP的通信9-3发出报文的标准步骤如下: 1. 定义数据成员 DatagramSocket socket; DatagramPacket packet; InetAddress address;(用来存放接收方的地址) int port; ;(用来存放接收方的端口号) 2. 创建数据报文Socket对象 try {socket=new DatagramSocket(1111);} catch(java.net.SocketException e) {} socket 绑定到一个本地的可用端口,等待接收客户的请求.40
  • 41. 基于UDP的通信9-43.分配并填写数据缓冲区(一个字节类型的数组) byte[] Buf=new byte[256]; 存放从客户端接收的请求信息. 4.创建一个DatagramPacket packet=new DatagramPacket(buf, 256); 用来从socket接收数据,它只有两个参数 5. 服务器阻塞 socket.receive(packet); 在客户的请求报道来之前一直等待 41
  • 42. 基于UDP的通信9-56. 从到来的包中得到地址和端口号 InetAddress address=packet.getAddress(); int port=packet.getPort(); 7. 将数据送入缓冲区 或来自文件,或键盘输入 8. 建立报文包,用来从socket上发送信息 packet=new DatagramPacket (buf,buf.length, address,port); 9. 发送数据包 10.关闭socket socket.send(packet); socket.close();42
  • 43. 基于UDP的通信9-6客户端接收包的步骤如下: 1. 定义数据成员 int port; InetAddress address; DatagramSocket socket; DatagramPacket packet; byte[] sendBuf=new byte[256]; 2. 建立socket socket=new DatagramSocket();43
  • 44. 基于UDP的通信9-73. 向服务器发出请求报文 address=InetAddress.getByName(args[0]); port=parseInt(args[1]); packet=new DatagramPacket(sendBuf,256,address,port); socket.send(packet); 这个包本身带有客户端的信息 4. 客户机等待应答 packet=new DatagramPacket(sendBuf,256); socket.receive(packet);(如果没有到就一直等待,因此实用程序要设置时间限度) 44
  • 45. 基于UDP的通信9-85. 处理接收到的数据 String received=new String(packet.getData(),0); System.out.println(received); 数据报套接字首先是强调发送方和接收方的区别,同时也指出服务器和客户之间的不同: 一个客户机必须事先知道服务器的地址和端口,以便进行出事连接 一个服务器从它接收到的数据报文中读取客户端的地址和端口.45
  • 46. 基于UDP的通信9-9.建立数据报socket();建立一个报文包packet等待请求报文建立数据报socket建立一个请求包发出请求获得对方地址构成信息包发送出去创建接收包等待接收46
  • 47. 8.3案例8及分析:SMTP邮件传送客户端 具体分析见书上47
  • 48. 8.4 扩展知识48
  • 49. 8.4.1 编写多客户服务器程序 实现多客户服务器,利用Java的多线程机制,将服务器写成多线程程序,不同的线程为不同的客户服务。 主线程只负责循环等待,其它线程负责网络连接,接收客户输入的信息。 在主线程中,利用ServerSocket.accept()等待用户连接,一旦客户端连接上服务器端套接字,则启动其它线程来响应客户端请求,完成对客户端的服务 49
  • 50. 小结2-1实现网络功能要靠URL类, URLConection类, Socket类和DatagramSocket类 网络上的数据传送是将网络连接转换成输入输出流 DataInputStream和DataOutputStream (PrintStream)是网间流的载体. URL适用于web应用,如访问http服务器是高层服务 URLConection的另一边通常是cgi程序50
  • 51. 小结2-2回环地址可用于在本地机器上调试网络程序 Socket适用于面向连接的,可靠性要求高的应用 Datagram适用于效率要求高的应用 Socket是由IP和端口构成的一种网上通信链路的一端 Socket通信要分别运行服务器和客户程序 服务器程序是多线程的,可处理多个客户的请求51