Download presentation
Presentation is loading. Please wait.
1
第十一章 Java的网络功能
2
主要内容: 1、了解URL的构成,学会利用URL读取网络资源 2、熟悉java.net包 3、了解TCP/IP协议
4、掌握Socket的基本使用方法,学会建立Socket连接,实现客户端和服务器端通信 5、掌握利用UDP通信的方法 6、了解多客户端通信概念,掌握进行多客户通信的方法
3
11.1基本知识 计算机网络就是利用通信线路连接起来的、相互独立的,计算机集合 11.1.2 计算机协议就是针对计算机进行通信时,关于信息交互方式、交互秩序等所作出的规定。 常用协议: TCP、IP、UDP、SNMP、SMTP、FTP、HTTP
4
11.1.3 Java的网络功能 作为一门成功的网络编程语言,Java为用户提供了十分完善的网络功能: 获取网络上的各种资源
获取网络上的各种资源 与服务器建立连接和通信 传递本地数据
5
11.1.4 通信模式 Java是通过使用流模式来实现网络信息交互的。这种模式下,一个接口同时拥有两个流--输入流和输出流。
当一个进程向另一个进程发送数据时,只需将数据写入到相应接口的输出流上,而另一个进程在接口的“另一端”从输入流上读取数据
6
11.1.5 Java.net包 Java.net包提供了低级和高级的网络功能。它包含了大部分用于访问网络资源的类。 一、用于网络定位的类
URL类 URLConnection类 HttpURLConnection类 InetAddress类
7
二、用于建立服务器和客户端通信的类 Socket类 ServerSocket类 三、基于数据报的通信DatagramSocket DatagramPacket类
8
11.2网络功能与使用方法 网络功能按层次与使用方法分为三类 11.2.1 URL
这种方法是通过URL的网络资源表达式形式确定数据在网络中的位置,利用URL类中提供的方法,直接读入网络中的数据,或者将本地数据传送到网络的另一端。
9
Socket 是指两个程序通过网络进行通信的一种方式。在TCP/ IP协议下,客户端和服务器端通常使用socket来进行信息交流。这种方式也是传统中常用的一种方式。 DataGram Datagram方式是三种网络功能中最低级的一种,它是一种面向非连接的、以数据报方式工作的通信。适用于网络状况不稳定下的数据传输和访问
10
11.3 URL 11.3.1 Internet上的寻址 IP是标识连接到Internet上的计算机的唯一的数字地址。
如: 人们更熟悉的是它的符号形式,也就是域名,如: 。
11
URL是Unoform Resource Locator的缩写。
<schme>://[<user>][:password]/ <usr-path> 如: download-windows.html
12
URL对象是通过定义在Java.net包中的URL类来进行构造的。构造方法有四种:
1.Public URL(String spec) spec--表示URL的字符串 例:URL url1=new URL(“ 2.Public URL(URL context,String spec) 用于表示相对URL位置的定义。 例:URL url2=new URL(getCodeBase(),”myfile.text”)
13
3.public URL(String protocol, String host,String file)
String host,int port,String file) String protocol--协议 String host--主机名 int port--端口 String file--文件名
14
例:URL url3=newURL(“http”, ”www.sohu.com”,”myfile.txt”)
在使用上述构造方法时,会存在某些问题,因此,在类URL的构造方法中都声明抛出非运行时异常--MalformedURLException,所以在生成URL对象时要捕获,进行异常处理。
15
Try{ URL url3=new URL(“http”, ” } catch(MalformedURLException e) { ….. } 三.常用方法 String getProtocol() 获取传输协议 String getHost() 获取主机名称 String getPort() 获取通信端口号 String getFile() String toString() 获取资源文件名称
16
例:链向另外的Web页UrlEx.java 创建URL对象、链接到相应主页的代码: {try {url1=new URL(s1); }
catch(MalformedURLException g) {System.out.println(“不正确的 URL:"+url1); text1.setText("哈尔滨工业大学"); getAppletContext().showDocument(url1);
17
InputStream openStream() 打开输入流 用以读取URL位置的数据,其返回值是一个InputStream数据流
例:读指定文件在屏幕上显示 ReadFromURL.java 用于建立流的代码: try{ url=new URL(getCodeBase(),"ReadFromUrl.java"); dis=new DataInputStream(url.openStream());} catch(MalformedURLException q) {System.out.println("MalformedURLException:"+q); }
18
从流中读取数据的代码: try{ while((readstring=dis.readLine())!=null) { e.drawString(readstring,10,i ); i=i+20; } e.drawString("end of the file",10,i); dis.close(); } catch(IOException g){ System.out.println("IOException:"+g);
19
11.4同服务器进行通信 11.4.1 套接字(Socket和ServerSocket) IP地址标识Internet上的计算机
端口号标识正在计算机上运行的进程 端口号定义为 之间的一个16位整数,其中0--1023被一些特定服务器占用如: telnet占用端口23 http占用端口80 SMTP占用端口25 普通用户端口号 只能是 之间 端口号与IP地址的组合得出一个网络套接字
20
11.4.2 客户端建立套接字 客户端程序可使用Socket类建立与服务器的套接字连接,Socket类的构造方法是:
客户端建立套接字 客户端程序可使用Socket类建立与服务器的套接字连接,Socket类的构造方法是: Socket(String host,int port) host---服务器地址 port---端口号 当 用本地机充当 服务器时,host 用“localhost”表示 例: Socket mysocket=new Socket( “ Socket mysocket=new Socket( “ localhost”,2880);
21
建立套接字时可能发生IOException异常,应当捕获,格式如下:
try{ Socket mysocket=new Socket( “ } catch(IOException e) {…..} 当套接字连接mysocket建立后可使用getInputStream()方法获得一个输入流,用于接收服务器发来的信息 使用getOutputStream()方法获得一个输出流,用于将信息发送至服务器端
22
11.4.3 建立服务器套接字 为响应客户端的呼叫,服务器端必须建立一个等待接收客户套接字的服务器套接字
建立服务器套接字 为响应客户端的呼叫,服务器端必须建立一个等待接收客户套接字的服务器套接字 可用ServerSocket类创建服务器套接字 Socket mysocket=new Socket(“ localhost”, 2880); ServerSocket的构造方法是: ServerSocket(int port) port--客户端建立连接时使用的同一端口号 ServerSocket serversocket=new ServerSocket(2880);
23
建立服务器套接字时可能发生IOException异常,应当捕获,格式如下:
try{ ServerSocket serversocket=new ServerSocket(2880); } catch(IOException e) {…..}
24
接收客户端套接字 当服务器端的套接字连接serversocket建立后,可使用ServerSocket类中的accept()方法接收客户端套接字mysocket, 格式为: Socket sc=serversocket.accept(); 接收客户端套接字的过程也可能发生IOException异常,应当捕获: try{ Socket sc=serversocket.accept(); } catch(IOException e){…..}
25
收到客户套接字后,放到一个Socket对象sc中,那么服务器套接字sc就是客户端套接字mysocket。
服务器端也可以通过服务器套接字sc使用方法 getInputStream() 获得一个输出流有,用于向客户端发送信息 使用方法 getOutputStream() 获得一个输入流,用于接收客户端发来的信息
26
网络连接模式 服务器端 客户端 Socket(host,port) ServerSocket(port) accept()
网络连接模式 接收客户 套接字 建立服务器端 套接字 建立客户端 套接字 服务器端 客户端 Socket(host,port) ServerSocket(port) accept() 获得客户端 输入输出流 获得服务器端 输入输出流 OutputStream OutputStream InputStream InputStream 至此,就将网络 通信转化为IO操作 close() close()
27
例:一个简单的通信程序客户端的主要代码 建立套接字, 获得IO对象 try{mysocket=new
Socket("localhost",3456); in=new DataInputStream( mysocket.getInputStream()); out=new DataOutputStream( mysocket.getOutputStream()); 向服务器发送信息 out.writeUTF("hello!"); 等待接收服务器 发送的信息 while(true) { s=in.readUTF(); if(s!=null) break;} mysocket.close(); }
28
catch(IOException e){
System.out.println("not connected");} System.out.println(s); } }
29
服务器端程序主要代码 建立服务器端 套接字 try{server=new ServerSocket(3456);}
catch(IOException e1){ System.out.println("Error:"+e1);} 接收客户端 套接字 try{ client=server.accept(); in=new DataInputStream( client.getInputStream()); out=new DataOutputStream( client.getOutputStream());
30
out.writeUTF("Hello,i am server."); you.close(); catch(IOException e){
while(true) { s=in.readUTF(); if(s!=null) break; } out.writeUTF("Hello,i am server."); you.close(); catch(IOException e){ System.out.println("Erro:"+e);} }} 接收客户端信息 并给出应答
31
s=new ServerSocket(portnub); …… for (;;)
五.服务多个客户 如果允许多个客户同时连接到服务器上,可以利用多线程来实现。 s=new ServerSocket(portnub); …… for (;;) {Socket incoming = s.accept( ); ….. new ThreadHandler(incoming, i).start(); i++; }
32
例:一个聊天程序 public void run() { try
{ DataInputstream in = new DataInputstream (incoming.getInputStream()); DataOutputStream out = new DataOutputStream (incoming.getOutputStream()); out.println( "Hello! Enter BYE to exit." ); boolean done = false; while (!done) { String str = in.readLine(); if (str == null) done = true; 。。。 例:一个聊天程序
33
11.5基于数据报的通信 数据报是一种无连接的通信服务 数据报的特点: 速度快 稳定性差
DatagramSocket类实现了一种适用于数据报的socket,用于监听本地主机上的指定端口 DatagramPacket类实现了从指定的缓冲区接收数据,通过DatagramSocket实例调用receive()使其处于堵塞状态,一直到接收到数据为止。
34
11.5.1 接收数据报 创建一个DatagramSocket实例用来监听本地主机上的指定端口
DatagramSocket socket=new DatagramSocket(9999); 创建一个Datagrampacket实例,用以从指定的缓冲区接收数据 DatagramPacket packet=new DatagramPacket(buffer,buffer.length); 用DatagramSocket提供的方法receive()接收数据 socket.receive(packet);
35
例:下面为一接收数据报程序 public class UDPGet extends Frame implements ActionListener {TextArea textArea1=new TextArea(); Button button1=new Button();
36
public static void main(String args[])
{ UDPGet get=new UDPGet(); get.setLocation(100,100); get.setSize(300,200); get.show(); get.waitForData(); }
37
public UDPGet() {try{ this.setTitle("接收数据报"); textArea1.setText(""); button1.setLabel("退出"); this.add(textArea1,BorderLayout.CENTER); this.add(button1,BorderLayout.SOUTH); button1.addActionListener(this);} catch(Exception e){e.printStackTrace() }}
38
void waitForData() { try{ byte[] buffer=new byte[1024]; DatagramPacket packet=new DatagramPacket(buffer,buffer.length); DatagramSocket socket=new DatagramSocket(9999);
39
while(true) {socket.receive(packet); String s=new String(buffer ,0,packet.getLength()); textArea1.append(s+"\n"); packet=new DatagramPacket( buffer,buffer.length); } } catch(Exception e){} }
40
public void actionPerformed(
ActionEvent e) {Component com= (Component)e.getSource(); if(com.equals(button1)) System.exit(0); }
41
二.发送数据报 首先创建一个DatagramPacket实例,用于指定要发送的数据、数据长度、目的地主机名的端口号
DatagramPacket packet=new DatagramPacket( message,len,”localhost”,9999); message为一byte型数组 再用DatagramSocket类对象的成员方法send() 来发送数据 socket.send(packet); 例:下面为一个发送数据的例子
42
public class UDPSend extends Frame
implements ActionListener { GridLayout net; TextField textField1=new TextField(); Button button1=new Button(); Button button2=new Button();
43
public static void main(String args[])
{ UDPSend send=new UDPSend(); send.setLocation(100,100); send.setSize(300,150); send.show(); }
44
public UDPSend() {try{ this.setTitle("发送数据报"); button1.setLabel("发送"); button2.setLabel("退出"); net=new GridLayout(3,1); setLayout(net); this.add(textField1,null); this.add(button1,null);
45
this.add(button2,null);
textField1.addActionListener(this); button2.addActionListener(this); button1.addActionListener(this); } catch(Exception e) {e.printStackTrace();
46
void sendData() { try {String msg=textField1.getText(); if(msg.equals("")) return; textField1.setText(""); InetAddress address=InetAddress .getByName("localhost"); int len=msg.length(); void sendData() { try {String msg=textField1.getText(); if(msg.equals("")) return; textField1.setText(""); InetAddress address=InetAddress getByName("localhost"); int len=msg.length(); byte[] message=new byte[len]; msg.getBytes(0,len,message,0); DatagramPacket packet=new DatagramPacket(message,len,address,9999); DatagramSocket socket=new DatagramSocket(); socket.send(packet);} catch(Exception e){} } public void actionPerformed(ActionEvent e) {Component com=(Component)e.getSource(); if(com.equals(button1)) sendData(); else if(com.equals(button2)) System.exit(0); else sendData(); } }
47
byte[] message=new byte[len];
msg.getBytes(0,len,message,0); DatagramPacket packet=new DatagramPacket( message,len,address,9999); DatagramSocket socket=new DatagramSocket(); socket.send(packet);} catch(Exception e){…..} }
48
public void actionPerformed(
ActionEvent e) {Component com=(Component )e.getSource(); if(com.equals(button1)) sendData(); else if(com.equals(button2)) System.exit(0); else sendData();} }
Similar presentations