Java网络编程技术1

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 class GetIP {

    public static void main(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 class GetMyIP {

    public static void main(String[] args) {
        try {
            System.out.println(InetAddress.getLocalHost());
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
    }
}

1.1.2 根据IP地址查找主机名

InetAddress亦可以根据给定的IP地址来查找对应的主机名。但要注意的是,它只能获取局域网内的主机名。

例3. 根据IP地址查找主机名。

package Net;
import java.net.*;
public class GetHostName {

    public static void main(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. 一个简单的浏览器示例。

package Net;
import javax.swing.*;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.*;
public class myBrowser implements ActionListener,HyperlinkListener {
    JFrame jf;
    JLabel jl;
    JTextField jtf;
    JPanel jp;
    JEditorPane content;
    JScrollPane jsp;
    Container con;
    public myBrowser(){
        jf = new JFrame("我的浏览器");
        jl = new JLabel("请输入URL地址:");
        jtf = new JTextField();
        jtf.addActionListener(this);
        jtf.setColumns(20);
        jp = new JPanel();
        jp.setLayout(new FlowLayout());
        jp.add(jl);
        jp.add(jtf);
        content = new JEditorPane();
        content.setEditable(false);
        content.addHyperlinkListener(this);
        jsp = new JScrollPane(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 void hyperlinkUpdate(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 void actionPerformed(ActionEvent e) {
        try {
            //根据用户输入构造URL对象
            URL url = new URL(jtf.getText());
            //获取网页内容并显示
            content.setPage(url);
        } catch (MalformedURLException e1) {
            System.out.println(e1.toString());
        } catch (IOException e1) {
            JOptionPane.showMessageDialog(jf, "找不到网页!");
        }
    }
    
    public static void main(String[] args){
        new myBrowser();
    }

}

上面的程序中,由于JEditorPane功能比较弱,无法执行网页中的JavaScript/VBScript等脚本语言,更无法执行ActiveX控件,所以只能用于一些静态网页的显示。

1.2.2 URLConnection类的使用——文件下载

文件下载的实质是从远程机器上复制文件到本地机器上,也就是说,它的本质不过是文件的复制。

例5. 文件下载示例。

package Net;
import javax.swing.*;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.*;
public class DownFile implements ActionListener {
    JFrame jf;
    Container con;
    JLabel jl;
    JTextField jtf;
    JButton btn;
    String name;
    public DownFile(){
        jf = new JFrame("我的浏览器");
        con = jf.getContentPane();
        jl = new JLabel("请输入要下载文件的地址及名称:");
        jtf = new JTextField();
        jtf.setColumns(20);
        btn = new JButton("下载");
        btn.addActionListener(this);
        con.setLayout(new FlowLayout());
        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 void actionPerformed(ActionEvent e) {
        try {
            name = JOptionPane.showInputDialog(jf, "请输入要保存的文件名");
            URL url = new URL(jtf.getText());
            //创建远程连接
            URLConnection connect = url.openConnection();
            //创建输入流
            BufferedReader buf = new BufferedReader(new InputStreamReader(connect.getInputStream()));
            //创建输出流,保存文件名为temp.dat
            BufferedWriter file = new BufferedWriter(new FileWriter(name));
            int ch;
            //复制文件
            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 void main(String[] args) {
        new DownFile();
    }
}

2. Java Socket应用

2.1 示例程序1——端到端的通信

例6. 一个简单的客户/服务器的Socket通信程序。

package Net;
import java.io.*;
import java.net.*;
public class Client {
    public static void main(String[] args) {
        try {
            //连接到本机,端口号为5500
            Socket s = new Socket("localhost",5500);
            DataOutputStream dos = new DataOutputStream(s.getOutputStream());
            DataInputStream dis = new DataInputStream(s.getInputStream());
            System.out.println("请输入半径数值发送到服务器,输入bye表示结束。");
            String outstr,instr;
            boolean goon = true;
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            while(goon){
                outstr = br.readLine();
                dos.writeUTF(outstr);
                dos.flush();
                instr = dis.readUTF();
                if(!instr.equals("bye"))
                    System.out.println("从服务器返回的结果为:"+instr);
                else
                    goon = false;
            }
            dis.close();
            dos.close();
            s.close();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}
package Net;
import java.io.*;
import java.net.*;
public class Server {
    public static void main(String[] args) {
        try {
            System.out.println("等待连接!");
            ServerSocket ss = new ServerSocket(5500);
            Socket s = ss.accept();
            System.out.println("连接者来自:"+s.getInetAddress().getHostAddress());
            DataInputStream dis = new DataInputStream(s.getInputStream());
            DataOutputStream dos = new DataOutputStream(s.getOutputStream());
            boolean goon = true;
            double radius,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.274333882308138
bye

服务器端:

等待连接!
连接者来自:127.0.0.1
接收到的半径为:2.0
圆面积12.566370614359172已发送
接收到的半径为:3.0
圆面积28.274333882308138已发送

2.2 示例程序2——一对多的通信

例7. 可以响应多个客户端的服务程序。

首先写一个服务器处理的线程类:

package Net;
import java.io.*;
import java.net.*;
public class ServerThread extends Thread {
    private DataInputStream dis = null;
    private DataOutputStream dos = null;
    private Socket s = null;
    String str;
    public ServerThread(Socket s) throws IOException{
        this.s = s;
        System.out.println("连接者来自:"+s.getInetAddress().getHostAddress());
        dis = new DataInputStream(s.getInputStream());
        dos = new DataOutputStream(s.getOutputStream());
        start();
    }
    
    public void run(){
        try {
            boolean goon = true;
            double radius,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();
        }
    }
}

写一个主程序使用线程:

package Net;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class MultiServer {
    public static void main(String[] args) {
        try {
            System.out.println("等待连接!");
            ServerSocket ss = new ServerSocket(5500);
            Socket s = null;
            while(true){
                s = ss.accept();
                new ServerThread(s);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

 2.3 示例程序3——简单的聊天程序

例8. 聊天程序示例。

服务器端:

package Net.chat;
import javax.swing.*;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.*;
public class chatServer implements ActionListener,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;
    
    public chatServer(){
        jf = new JFrame("聊天————服务器");
        con = jf.getContentPane();
        jp = new JPanel();
        jp.setLayout(new FlowLayout());
        showArea = new JTextArea();
        showArea.setEditable(false);
        msgText = new JTextField();
        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 = new DataInputStream(s.getInputStream());
            dos = new DataOutputStream(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 void run() {
        try {
            while(true){
                showArea.append("对方说:"+dis.readUTF()+"\n");
                Thread.sleep(1000);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void actionPerformed(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 void main(String[] args) {
        new chatServer();
    }
}

客户端:

package Net.chat;
import javax.swing.*;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.*;
public class chatClient implements ActionListener,Runnable{
    JFrame jf;
    Container con;
    JPanel jp;
    JTextArea showArea;
    JTextField msgText;
    JButton btn;
    Thread thread;
    Socket s = null;
    DataInputStream dis = null;
    DataOutputStream dos = null;
    
    public chatClient(){
        jf = new JFrame("聊天————客户端");
        con = jf.getContentPane();
        jp = new JPanel();
        jp.setLayout(new FlowLayout());
        showArea = new JTextArea();
        showArea.setEditable(false);
        msgText = new JTextField();
        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 = new DataInputStream(s.getInputStream());
            dos = new DataOutputStream(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 void run() {
        try {
            while(true){
                showArea.append("对方说:"+dis.readUTF()+"\n");
                Thread.sleep(1000);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void actionPerformed(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 void main(String[] args) {
        new chatClient();
    }
}

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。