1. Java网络编程常用API
1.1 InetAddress类使用示例
1.1.1根据域名查找IP地址
获取用户通过命令行方式指定的域名,然后通过InetAddress对象来获取该域名对应的IP地址。当然,程序运行时,需要计算机正常连接到Internet上。
例1. 根据域名查找IP地址
package Net;
import java.net.InetAddress;
import java.net.UnknownHostException;public classGetIP {public static voidmain(String[] args) {try{
InetAddress ad= InetAddress.getByName(args[0]);//ad.getHostAddress()方法获取当前对象的IP地址
System.out.println("IP地址为:"+ad.getHostAddress());
}catch(UnknownHostException e) {
e.printStackTrace();
}
}
}
想获取网易的IP地址,就应该输入:java GetIP www.163.com
例2. 获取本机的IP地址。
package Net;
import java.net.*;public classGetMyIP {public static voidmain(String[] args) {try{
System.out.println(InetAddress.getLocalHost());
}catch(UnknownHostException e) {
e.printStackTrace();
}
}
}
1.1.2 根据IP地址查找主机名
InetAddress亦可以根据给定的IP地址来查找对应的主机名。但要注意的是,它只能获取局域网内的主机名。
例3. 根据IP地址查找主机名。
packageNet;import java.net.*;public classGetHostName {public static voidmain(String[] args) {try{
InetAddress ad= InetAddress.getByName(args[0]);
System.out.println("主机名为:"+ad.getHostName());
}catch(UnknownHostException e) {
e.printStackTrace();
}
}
}
如果输入:java GetHostName www.sina.com
输出结果为: 主机名为:www.sina.com
如果输入的为局域网内的IP地址: java GetHostName 192.168.1.154
输出结果为: 主机名为:Tangliang
如果没有找到原样输出。
1.2 URL类和URLConnection类的使用
1.2.1 URL类的使用——一个简单的浏览器
这个程序的交互界面只有两个主要控件:JTextField和JEditPane。用户在JTextField中输入URL,完成后按回车键,程序将利用JEditPane来显示网页内容。
例4. 一个简单的浏览器示例。
packageNet;import javax.swing.*;importjavax.swing.event.HyperlinkEvent;importjavax.swing.event.HyperlinkListener;importjava.awt.BorderLayout;importjava.awt.Container;importjava.awt.FlowLayout;importjava.awt.event.ActionEvent;importjava.awt.event.ActionListener;importjava.io.IOException;import java.net.*;public class myBrowser implementsActionListener,HyperlinkListener {
JFrame jf;
JLabel jl;
JTextField jtf;
JPanel jp;
JEditorPane content;
JScrollPane jsp;
Container con;publicmyBrowser(){
jf= new JFrame("我的浏览器");
jl= new JLabel("请输入URL地址:");
jtf= newJTextField();
jtf.addActionListener(this);
jtf.setColumns(20);
jp= newJPanel();
jp.setLayout(newFlowLayout());
jp.add(jl);
jp.add(jtf);
content= newJEditorPane();
content.setEditable(false);
content.addHyperlinkListener(this);
jsp= newJScrollPane(content);
con=jf.getContentPane();
con.add(jp, BorderLayout.NORTH);
con.add(jsp, BorderLayout.CENTER);
jf.setSize(800, 600);
jf.setLocation(300, 200);
jf.setVisible(true);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}public voidhyperlinkUpdate(HyperlinkEvent e) {if(e.getEventType()==HyperlinkEvent.EventType.ACTIVATED){try{
URL url= e.getURL(); //获取用户单击的URL
content.setPage(url); //跳转到新页面
jtf.setText(url.toString()); //更新用户输入框中的URL
} catch(IOException e1) {
JOptionPane.showMessageDialog(jf,"找不到网页!");
}
}
}public voidactionPerformed(ActionEvent e) {try{//根据用户输入构造URL对象
URL url = newURL(jtf.getText());//获取网页内容并显示
content.setPage(url);
}catch(MalformedURLException e1) {
System.out.println(e1.toString());
}catch(IOException e1) {
JOptionPane.showMessageDialog(jf,"找不到网页!");
}
}public static voidmain(String[] args){newmyBrowser();
}
}
上面的程序中,由于JEditorPane功能比较弱,无法执行网页中的JavaScript/VBScript等脚本语言,更无法执行ActiveX控件,所以只能用于一些静态网页的显示。
1.2.2 URLConnection类的使用——文件下载
文件下载的实质是从远程机器上复制文件到本地机器上,也就是说,它的本质不过是文件的复制。
例5. 文件下载示例。
packageNet;import javax.swing.*;importjava.awt.Container;importjava.awt.FlowLayout;importjava.awt.event.ActionEvent;importjava.awt.event.ActionListener;importjava.io.BufferedReader;importjava.io.BufferedWriter;importjava.io.FileWriter;importjava.io.IOException;importjava.io.InputStreamReader;import java.net.*;public class DownFile implementsActionListener {
JFrame jf;
Container con;
JLabel jl;
JTextField jtf;
JButton btn;
String name;publicDownFile(){
jf= new JFrame("我的浏览器");
con=jf.getContentPane();
jl= new JLabel("请输入要下载文件的地址及名称:");
jtf= newJTextField();
jtf.setColumns(20);
btn= new JButton("下载");
btn.addActionListener(this);
con.setLayout(newFlowLayout());
con.add(jl);
con.add(jtf);
con.add(btn);
jf.setSize(800, 600);
jf.setLocation(300, 200);
jf.setVisible(true);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}public voidactionPerformed(ActionEvent e) {try{
name= JOptionPane.showInputDialog(jf, "请输入要保存的文件名");
URL url= newURL(jtf.getText());//创建远程连接
URLConnection connect =url.openConnection();//创建输入流
BufferedReader buf = new BufferedReader(newInputStreamReader(connect.getInputStream()));//创建输出流,保存文件名为temp.dat
BufferedWriter file = new BufferedWriter(newFileWriter(name));intch;//复制文件
while((ch=buf.read())!=-1){
file.write(ch);
}
buf.close();
file.close();
JOptionPane.showMessageDialog(jf,"下载成功!");
}catch(MalformedURLException e1) {
System.out.println(e1.toString());
}catch(IOException e1) {
JOptionPane.showMessageDialog(jf,"连接出错!");
}
}public static voidmain(String[] args) {newDownFile();
}
}
2. Java Socket应用
2.1 示例程序1——端到端的通信
例6. 一个简单的客户/服务器的Socket通信程序。
packageNet;import java.io.*;import java.net.*;public classClient {public static voidmain(String[] args) {try{//连接到本机,端口号为5500
Socket s = new Socket("localhost",5500);
DataOutputStream dos= newDataOutputStream(s.getOutputStream());
DataInputStream dis= newDataInputStream(s.getInputStream());
System.out.println("请输入半径数值发送到服务器,输入bye表示结束。");
String outstr,instr;boolean goon = true;
BufferedReader br= new BufferedReader(newInputStreamReader(System.in));while(goon){
outstr=br.readLine();
dos.writeUTF(outstr);
dos.flush();
instr=dis.readUTF();if(!instr.equals("bye"))
System.out.println("从服务器返回的结果为:"+instr);elsegoon= false;
}
dis.close();
dos.close();
s.close();
}catch(UnknownHostException e) {
e.printStackTrace();
}catch(IOException e) {
e.printStackTrace();
}
}
}
packageNet;import java.io.*;import java.net.*;public classServer {public static voidmain(String[] args) {try{
System.out.println("等待连接!");
ServerSocket ss= new ServerSocket(5500);
Socket s=ss.accept();
System.out.println("连接者来自:"+s.getInetAddress().getHostAddress());
DataInputStream dis= newDataInputStream(s.getInputStream());
DataOutputStream dos= newDataOutputStream(s.getOutputStream());boolean goon = true;doubleradius,area;
String str;while(goon){
str=dis.readUTF();if(!str.equals("bye")){
radius=Double.parseDouble(str);
System.out.println("接收到的半径为:"+radius);
area= radius*radius*Math.PI;
dos.writeUTF(Double.toString(area));
dos.flush();
System.out.println("圆面积"+area+"已发送");
}else{
dos.writeUTF("bye");
dos.flush();
goon= false;
}
}
dis.close();
dos.close();
ss.close();
}catch(IOException e) {
e.printStackTrace();
}
}
}
程序运行结果如下:
客户端:
请输入半径数值发送到服务器,输入bye表示结束。2从服务器返回的结果为:12.566370614359172
3从服务器返回的结果为:28.274333882308138bye
服务器端:
等待连接!
连接者来自:127.0.0.1接收到的半径为:2.0圆面积12.566370614359172已发送
接收到的半径为:3.0圆面积28.274333882308138已发送
2.2 示例程序2——一对多的通信
例7. 可以响应多个客户端的服务程序。
首先写一个服务器处理的线程类:
packageNet;import java.io.*;import java.net.*;public class ServerThread extendsThread {private DataInputStream dis = null;private DataOutputStream dos = null;private Socket s = null;
String str;public ServerThread(Socket s) throwsIOException{this.s =s;
System.out.println("连接者来自:"+s.getInetAddress().getHostAddress());
dis= newDataInputStream(s.getInputStream());
dos= newDataOutputStream(s.getOutputStream());
start();
}public voidrun(){try{boolean goon = true;doubleradius,area;
String str;while(goon){
str=dis.readUTF();if(!str.equals("bye")){
radius=Double.parseDouble(str);
System.out.println("接收到的半径为:"+radius);
area= radius*radius*Math.PI;
dos.writeUTF(Double.toString(area));
dos.flush();
System.out.println("圆面积"+area+"已发送");
}else{
dos.writeUTF("bye");
dos.flush();
goon= false;
}
}
dis.close();
dos.close();
s.close();
}catch(NumberFormatException e) {
e.printStackTrace();
}catch(IOException e) {
e.printStackTrace();
}
}
}
写一个主程序使用线程:
packageNet;importjava.io.IOException;importjava.net.ServerSocket;importjava.net.Socket;public classMultiServer {public static voidmain(String[] args) {try{
System.out.println("等待连接!");
ServerSocket ss= new ServerSocket(5500);
Socket s= null;while(true){
s=ss.accept();newServerThread(s);
}
}catch(IOException e) {
e.printStackTrace();
}
}
}
2.3 示例程序3——简单的聊天程序
例8. 聊天程序示例。
服务器端:
packageNet.chat;import javax.swing.*;importjava.awt.BorderLayout;importjava.awt.Container;importjava.awt.FlowLayout;importjava.awt.event.ActionEvent;importjava.awt.event.ActionListener;importjava.io.DataInputStream;importjava.io.DataOutputStream;importjava.io.IOException;import java.net.*;public class chatServer implementsActionListener,Runnable{
JFrame jf;
Container con;
JPanel jp;
JTextArea showArea;
JTextField msgText;
JButton btn;
Thread thread;
ServerSocket ss= null;
Socket s= null;
DataInputStream dis= null;
DataOutputStream dos= null;publicchatServer(){
jf= new JFrame("聊天————服务器");
con=jf.getContentPane();
jp= newJPanel();
jp.setLayout(newFlowLayout());
showArea= newJTextArea();
showArea.setEditable(false);
msgText= newJTextField();
msgText.setColumns(20);
btn= new JButton("发送");
btn.addActionListener(this);
jp.add(msgText);
jp.add(btn);
con.add(showArea, BorderLayout.CENTER);
con.add(jp, BorderLayout.SOUTH);
jf.setSize(500, 400);
jf.setLocation(300, 200);
jf.setVisible(true);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);try{
ss= new ServerSocket(8000);
showArea.append("正在等待对话请求!\n");
s=ss.accept();
dis= newDataInputStream(s.getInputStream());
dos= newDataOutputStream(s.getOutputStream());
thread= new Thread(this);
thread.setPriority(Thread.MIN_PRIORITY);
thread.start();
}catch(IOException e) {
showArea.append("对不起,没能创建服务器!\n");
msgText.setEditable(false);
btn.setEnabled(false);
}
}public voidrun() {try{while(true){
showArea.append("对方说:"+dis.readUTF()+"\n");
Thread.sleep(1000);
}
}catch(IOException e) {
e.printStackTrace();
}catch(InterruptedException e) {
e.printStackTrace();
}
}public voidactionPerformed(ActionEvent e) {
String msg=msgText.getText();try{if(msg.length()>0){
dos.writeUTF(msg);
dos.flush();
showArea.append("我说:"+msg+"\n");
msgText.setText(null);
}
}catch(IOException e1) {
showArea.append("你的消息"+msg+"未能发送出去!\n");
}
}public static voidmain(String[] args) {newchatServer();
}
}
客户端:
packageNet.chat;import javax.swing.*;importjava.awt.BorderLayout;importjava.awt.Container;importjava.awt.FlowLayout;importjava.awt.event.ActionEvent;importjava.awt.event.ActionListener;importjava.io.DataInputStream;importjava.io.DataOutputStream;importjava.io.IOException;import java.net.*;public class chatClient implementsActionListener,Runnable{
JFrame jf;
Container con;
JPanel jp;
JTextArea showArea;
JTextField msgText;
JButton btn;
Thread thread;
Socket s= null;
DataInputStream dis= null;
DataOutputStream dos= null;publicchatClient(){
jf= new JFrame("聊天————客户端");
con=jf.getContentPane();
jp= newJPanel();
jp.setLayout(newFlowLayout());
showArea= newJTextArea();
showArea.setEditable(false);
msgText= newJTextField();
msgText.setColumns(20);
btn= new JButton("发送");
btn.addActionListener(this);
jp.add(msgText);
jp.add(btn);
con.add(showArea, BorderLayout.CENTER);
con.add(jp, BorderLayout.SOUTH);
jf.setSize(500, 400);
jf.setLocation(300, 200);
jf.setVisible(true);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);try{
s= new Socket("localhost",8000);
showArea.append("连接成功,请说话!\n");
dis= newDataInputStream(s.getInputStream());
dos= newDataOutputStream(s.getOutputStream());
thread= new Thread(this);
thread.setPriority(Thread.MIN_PRIORITY);
thread.start();
}catch(IOException e) {
showArea.append("对不起,没能连接到服务器!\n");
msgText.setEditable(false);
btn.setEnabled(false);
}
}public voidrun() {try{while(true){
showArea.append("对方说:"+dis.readUTF()+"\n");
Thread.sleep(1000);
}
}catch(IOException e) {
e.printStackTrace();
}catch(InterruptedException e) {
e.printStackTrace();
}
}public voidactionPerformed(ActionEvent e) {
String msg=msgText.getText();try{if(msg.length()>0){
dos.writeUTF(msg);
dos.flush();
showArea.append("我说:"+msg+"\n");
msgText.setText(null);
}
}catch(IOException e1) {
showArea.append("你的消息"+msg+"未能发送出去!\n");
}
}public static voidmain(String[] args) {newchatClient();
}
}