《Java语言程序设计》课件第10章_第1页
《Java语言程序设计》课件第10章_第2页
《Java语言程序设计》课件第10章_第3页
《Java语言程序设计》课件第10章_第4页
《Java语言程序设计》课件第10章_第5页
已阅读5页,还剩55页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

10.1InetAddress类和URL类10.2流套接字Socket编程

10.3数据报UDP编程10.4小结

10.5习题

10.1.1InetAdress类

J包中的InetAddress类封装了Java对IP地址的处理,是Java对IP地址的一些处理。InetAddress有两个子类Inet4Address和Inet6Address,分别实现IPV4地址和IPV6地址,InetAddress是其二者的父类,既可以实现IPV4地址,也可以实现IPV6地址。10.1InetAddress类和URL类

InetAddress对象保存了网络中计算机的主机名和IP地址,可以通过调用以下静态方法来获取:

● getLocalhost()方法可以获取本机的IP地址,如果网络适配器设置了IP则显示IP,没有设置则返回本机回环地址。

● getByName(Stringhost)方法可以获取由host参数指定计算机的IP地址。

●getAllByName(Stringhost)方法可以获取由host参数指定计算机的多个IP地址,Internet上有些机器除了回环地址,还会随网络适配器不同而设置多个不同的IP地址,该方法返回的IP地址存储在对象数组中。● getByAddress(byte[]addr)方法通过addr字节数组(IPV4为4字节地址,IPV6为10字节地址)来创建一个IP地址对象。

● getByAddress(Stringhost,byte[]addr)方法由host指定的主机和addr字节数组指定的IP来创建一个IP地址对象。

若指定的主机名或IP地址无法解析,则会显示异常,一般以try{}catch{}结构捕获异常,即

try

{InetAddressaddress=InetAddress.getByName("");}

catch(UnknownHostExceptionex)

{System.out.println("Couldnotfindcn.suncom");}例10-1用InetAdress类的方法来获取本机地址、本机回路地址,以及远程的地址。

【例10-1】InetAdress类的使用。

import.*;

publicclassIPAddress

{

publicstaticvoidmain(String[]args)throwsUnknownHostException{ InetAddressaddr1=InetAddress.getLocalHost();

InetAddressaddr2=InetAddress.getByName("");

InetAddressaddr3=InetAddress.getByName("localhost");

System.out.println(addr1);

System.out.println("主机名: "+addr1.getHostName()+"IP地址:"+addr1.getHostAddress()+"\n");

System.out.println("SUN公司主机:"); System.out.println(addr2);

System.out.println("主机名: "+addr2.getHostName()+"IP地址:"+addr2.getHostAddress()+"\n");

System.out.println("本机回路地址:");

System.out.println(addr3);

System.out.println("主机名: "+addr3.getHostName()+"IP地址:"+addr3.getHostAddress());

}

}

运行结果如图10-1所示。图10-1IP地址10.1.2URL类

URL(UniformResourceLocator)统一资源定位符用来表示Ineternet上某个资源的地址,其语法格式如下:

protocol://host[:port]/path

protocol://username:password@host[:port]/path

其中,protocol为具体的协议,如http、ftp、file等;host为主机名;port为协议所使用的端口号;path为资源的路径名。第二种格式常用于ftp文件传输的资源获取。username和password分别为用户名和用户口令。

Java使用URL类的各种构造方法来构造URL对象,具体如下:

● publicURL(Stringspec):通过字符串spec参数来指定一个URL对象,如:

URLurl=newURL(“”);

● publicURL(URLcontext,Stringspec):通过参数context基本的URL地址,再来构造与之相对位置的URL。如URLcontext=newURL("");URLurl=newURL(context,"index.htm"),就是构造了一个相对与基地址的资源“index.html”。● publicURL(Stringprotocol,Stringhost,Stringfile):通过protocol来指定协议,host参数指定主机,file指定具体的资源文件。

● publicURL(Stringprotocol,Stringhost,intport,Stringfile):同上构造方法,只是端口不同时通过port参数来指定。

若构造URL的字符不符合URL地址规范,则会显示MalformedURLException异常,如:

try

{URLu1=newURL(“”);

}catch(MalformedURLExceptionex){}此外,URL类还提供一些方法来获取URL对象的不同部分:getProtocol()获取协议名称,getHost()获取主机名,getPort()获取资源的端口号,getFile()获取具体资源文件名,getPath()获取资源的URL路径,getAuthority()获取URL的权限信息等。

URL对象通过调用openStream()来获取InputStream的数据流。如例10-2创建一个URL对象u,再调用openStream()方法将获取资源的字符流读入流对象in中,并将读入的流一行行加入文本区域taf中。例程运行结果如图10-2所示。【例10-2】读取远程文件。

importjava.awt.*;

importjava.awt.event.*;

importjavax.swing.*;

import.*;

importjava.io.*;

publicclassShowWebFileextendsJFrame

{

privateJlabellfn=newJlabel("文件名:"); privateJtextFieldtfu=newJtextField("//index.php",20);

privateJbuttonsearb=newJbutton("查找");

privateJtextAreataf=newJtextArea();

privateJlabellstatus=newJlabel();

privateJpanelp=newJpanel();

publicShowWebFile(Strings)

{ super(s);

Containerc=getContentPane();

searb.addActionListener(newActionListener()

{

publicvoidactionPerformed(ActionEvente)

{ Stringline;

Stringfilename=tfu.getText();

taf.setText(null);

try{ URLu=newURL(filename);

InputStreamin=u.openStream();

BufferedReaderinFile=newBufferedReader(newInputStreamReader(in));

while((line=inFile.readLine())!=null)

{

taf.append(line+'\n');

}

lstatus.setText(filename+"文件读取成功!");}

catch(MalformedURLExceptionex){lstatus.setText(filename+

“文件格式错误!”);}

catch(FileNotFoundExceptionex){lstatus.setText(filename+

"文件没有发现!");}

catch(IOExceptionex){lstatus.setText(ex.toString());}

}

});

c.setLayout(newBorderLayout());

c.add(p,BorderLayout.NORTH); c.add(newJscrollPane(taf),BorderLayout.CENTER);

c.add(lstatus,BorderLayout.SOUTH);

p.setLayout(newBorderLayout());

p.add(lfn,BorderLayout.WEST);

p.add(tfu,BorderLayout.CENTER);

p.add(searb,BorderLayout.EAST);

} publicstaticvoidmain(String[]args)

{

ShowWebFilef=newShowWebFile(“显示远程文件”);

f.setSize(500,300);

f.setVisible(true);

f.setDefaultCloseOperation(Jframe.EXIT_ON_CLOSE);

}

}图10-2URL获取资源网络套接字是对网络通信的一种抽象,可以将其想象为一种连接设备,这个设备将网络上的数据流连接传输到用户程序中。连接网络两端各有一个套接字,套接字之间是一条网络通信线路,服务器上的应用程序和客户端上的应用程序通过套接字来传输数据流,可以忽略网络上数据流传输的细节。

流套接字使用TCP协议来进行传输控制,它是一种面向连接的协议,能够检测数据在传输过程中丢失的包,以便重新传输。10.2流套接字Socket编程

Java套接字Socket编程一般有两个类型:套接字(Socket)和服务器套接字(ServerSocket),用来实现客户端/服务器(C/S)结构的编程。使用Socket编程一般是在服务器端监听(Listen)某个端口是否有客户端的请求,当客户端发出连接请求后,服务器端接受(Accept)请求,并发送accept的消息,这样连接建立起来以后,通过send()等方法就可以发送和接收数据。一般Socket过程为:创建Socket,打开输入/输出流,进行读/写操作,关闭Socket。

Socket和ServerSocket构造方法可通过不同的参数,诸如IP地址、端口号等来创建。Socket和ServerSocket通过getInputStream()和getOutputStream()来获取对应的输入/输出流,实现网络数据的读/写操作,ServerSocket调用accetp()方法来接收连接,调用close()方法来关闭Socket。

例10-3构建了一个ServerSocket的服务器端程序。例10-4构建了一个客户端Socket,ServerSocket和Socket之间互相通信来传输信息。【例10-3】服务器端程序MyServer.java。

import.*;

importjava.io.*;

publicclassMyServer

{

publicstaticvoidmain(String[]args)throwsIOException

{

ServerSocketserver=newServerSocket(8080);

try

{System.out.println

("服务器程序启动,开始监听客户的请求...");

Socketskt=server.accept();

try

{

 System.out.println("接受客户:"+skt.getInetAddress()+"的连接请求,开始通信...");

 DataInputStreamin=newDataInputStream(newBufferedInputStream(skt.getInputStream()));

DataOutputStreamout=newDataOutputStream(newBufferedOutputStream

(skt.getOutputStream()));while(true)

{

doublelength=in.readDouble();

System.out.println("从客户接收到圆的直径:"+length);

doublearea=Math.PI*length*length;

out.writeDouble(area);

out.flush();

System.out.println("圆的面积为:"+area);

inti=in.readInt();

if(i==0)break;}

}catch(IOExceptione){System.err.println(e);}

finally{skt.close();System.out.println("通信结束!");}

}catch(IOExceptione){System.err.println(e);}

finally{server.close();}

}

}【例10-4】客户端程序MyClient.java。

import.*;

importjava.io.*;

publicclassMyClient

{

publicstaticvoidmain(String[]args)throwsException

{

InetAddressaddr=InetAddress.getByName("localhost");

Socketskt=newSocket(addr,8080);

try

{DataInputStreamin=newDataInputStream(newBufferedInputStream

(skt.getInputStream()));

DataOutputStreamout=newDataOutputStream(newBufferedOutputStream

(skt.getOutputStream()));

BufferedReaderstdin=newBufferedReader(newInputStreamReader(System.in),1);

stop:while(true)

{System.out.print("请输入圆的直径:");

Strings1=stdin.readLine();

doublelength=Double.parseDouble(s1);

out.writeDouble(length);

out.flush();

doublearea=in.readDouble();

System.out.println("从服务器接收到圆的面积为:"+area);

while(true)

{System.out.print("继续计算?(Y/N)");

Strings2=stdin.readLine();

if(s2.equals("N")||s2.equals("n"))

{

out.writeInt(0);

out.flush();

breakstop;

}

elseif(s2.equals("Y")||s2.equals("y"))

{out.writeInt(1);

out.flush();

break;

}

}

 }

}

catch(IOExceptione){System.err.println(e);}

finally{skt.close();}

}

}在MyServer.java程序中创建ServerSocket,ServerSocket接受的连接对象为skt,Server端等待客户端连接,连接建立后输出“接受客户xxx.xxx.xxx.xxx的连接请求,开始通信…”,并等待客户端输入信息,读入输入流后(客户端输出的圆半径值)后,进行运算,最后将结果通过输出流发送给客户端。运行结果如图10-3所示。

在MyClient.java中创建一个Socket对象,其IP地址为本机IP,端口号与服务器端的端口号8080相同,客户端从键盘读取输入数据后,经输出流输出圆的直径值,传递给服务器端进行运算,客户端skt对象的输入流接收来自服务器的圆面积运算结果,然后输出。运行结果如图10-4所示。图10-3服务器端运行

图10-4客户端运行上述服务器端程序只能接收单个客户的连接请求,若为多个用户提供连接,则需为每个客户在连接时创建一个线程,可结合多线程程序来改造上述程序,详细程序略,可参考相关资料。

UDP(UserDatagramProtocol,用户数据报协议)是一种简单的协议,可以实现快速的数据传输,它是一种面向无连接的通信,虽然定义了数据报的传送,但不保证数据传送的顺序、丢包等,其可靠性较差。TCP协议是基于数据流的方式来实现数据传输的,而UDP协议基于数据报传输数据。其到达的时间、内容是否完整不得而知,因此一般比较适宜在网络速度要求高而可靠性要求不高的场合,如网络上的DNS域名解析服务(53端口)就是通过UDP协议来实现的。10.3数据报UDP编程在包中有两个类DatagramSocket和DatagramPacket,用于实现UDP网络通信程序设计。应用DategramPacket类来创建UDP的数据报,用DatagramSocket类来创建服务器端和客户端的数据报套接字。

数据报根据用途可分为两种:发送数据和接收数据。接收数据报的构造方法有publicDatagramPacket(byte[]buf,intlength)和DatagramPacket(byte[]buf,intoffset,intlength)。其中,参数buf用来指定接收内容存储在字节数组buf中,length为长度,offset为偏移值。如:

byte[]buffer=newbyte[8912];

DatagramPacketdatap=new

DatagramPacket(buffer,buffer.length());发送数据报的构造方法有publicDatagramPacket(byte[]buf,intlength,InetAddressaddress,intport)和publicDatagramPacket(byte[]buf,intoffset,intlength,InetAddressaddress,intport)。发送数据报不但要指定发送的字节数组buf和长度,同时还要指定发送数据报的地址和端口号。如:

try{

InetAddressserver=InetAddress.getByName("22");

intport=53;

Stringstr="Thisisatest";byte[]data=str.getBytes();

DatagramPacketoutgoing=newDatagramPacket(data,data.length,server,port);

...

}catch(IOExceptione){...}应用UDP发送或接收数据时,需要创建数据报的套接字,创建数据报套接字由DatagramSocket方法来实现,DatagramSocket既可以用在服务器端的套接字也可以用在客户端的套接字上,其构造方法有:publicDatagramSocket()、publicDatagramSocket(intport)和publicDatagramSocket(intport,InetAddressladdr),这三种方法都会显示SocketException的异常。若有参数port,则指定port端口上的通信;否则系统自动指定一个可用端口来创建套接字。套接字创建后通过send(DatagramPacketp)和receive(DatagramPacketp)来发送或接收一个数据报,通信完成后调用close()方法关闭数据报套接字,并释放系统资源。下面通过一个具体的例子,介绍实现UDP服务器和客户机的编程方法。在例子中,服务器端的程序不间断地监听本机端口,一旦收到客户端发来的数据报,就回应一个简单的信息以通知客户已经收到了数据报;客户端程序向服务器发送一个包含一个字符串的数据报,同时告知服务器自己的地址及端口,以便服务器作出回应。【例10-5】服务器端程序UDPServerThread.java。

//UDP服务器端程序

importjava.io.*;

import.*;

importjava.util.*;

class

UDPServerThreadextendsThread

{//启动服务器线程的主程序

privateDatagramPacketpacket;

privateDatagramSocketsocket;

staticfinalintsport=1777;

UDPServerThread(){

try

{//将Socket连接到本机的一个可用的端口上

socket=newDatagramSocket(sport);

System.out.println("Listeningonport:"+socket.getLocalPort());

}

catch(Exceptione)

{

System.out.println("Error:"+e);

}

}

publicvoidrun()

{//线程的主要操作

if(socket==null)return;

while(true)

{

try

{

InetAddressaddress;

intcport;

byte[]buf=newbyte[1000];

Strings=“Yourpacketisreceived”;

packet=newDatagramPacket(buf,buf.length); //生成一个接收数据报

socket.receive(packet); //接收数据报

Strings1=newString(packet.getData());

System.out.println(“Receivedfromclient:”+s1);

//打印数据报的内容

address=packet.getAddress();

cport=packet.getPort(); //获得数据报的源地址与端口

s.getBytes(0,s.length(),buf,0);

packet=newDatagramPacket(buf,buf.length,address,cport);

//生成发送的数据报

socket.send(packet);

//发送数据报给客户

}

catch(Exceptione)

{

System.out.println("Error:"+e);

}

}

}

protectedvoidfinalize()

{

if(socket!=null)

{

socket.close();//关闭socket

System.out.println("SocketClosed.");

}

}

publicstaticvoidmain(String[]args)

{

UDPServerThreadserver=newUDPServerThread();

server.start();

}

}【例10-6】客户端程序UDPclient.java。

//UDP客户端程序

importjava.io.*;

import.*;

importjava.util.*;

classUDPclient

{

publicstaticvoidmain(String[]args)

{DatagramSocketsocket; //用于发送接收UDP

DatagramPacketpacket; //用于保存UDP

的内容

InetAddressaddress;

intport;

byte[]buf=newbyte[1000];

Strings="Hello,server!";

if(args.length<3)

{

System.out.println

("输入本地端口号,服务器名,服务器端口号");

System.exit(0);

}

try

{

socket=newDatagramSocket(Integer.parseInt(args[0]));

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论