Java网络编程技术2

3. UDP数据报通信

UDP通信中,需要建立一个DatagramSocket,与Socket不同,它不存在“连接”的概念,取而代之的是一个数据报包——DatagramPacket。这个数据报包必须知道自己来自何处,以及打算去哪里。所以本身必须包含IP地址、端口号和数据内容。

3.1 示例程序——用UDP实现的聊天程序

用UDP协议通信不需要使用服务器,所以用于聊天的程序只要写一个,分别在不同的机器上运行就可以了,而无须写成服务端和客户端两种形式。

例9. 用UDP实现的聊天程序示例。

package Net.UDPchat;
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.*;

import javax.swing.*;
public class UDPchat implements ActionListener,Runnable {
    JFrame jf;
    JLabel jl1,jl2,jl3;
    JTextField recPortText,sendPortText,IPText,msgText;
    JButton startBtn,sendBtn;
    JTextArea showArea;
    JScrollPane jsp;
    JPanel jp1,jp2;
    Container con;
    Thread thread = null;
    DatagramSocket receiveSocket,sendSocket;
    DatagramPacket receivePack,sendPack;
    private InetAddress sendIP;
    private int sendPort,recPort;
    private byte inBuf[],outBuf[];
    private static final int BUFSIZE = 1024;

    public UDPchat(){
        jf = new JFrame("聊天————UDP协议");
        jl1 = new JLabel("接收端口号:");
        jl2 = new JLabel("发送端口号:");
        jl3 = new JLabel("对方的地址:");
        recPortText = new JTextField();
        recPortText.setColumns(5);
        sendPortText = new JTextField();
        sendPortText.setColumns(5);
        IPText = new JTextField();
        IPText.setColumns(8);
        msgText = new JTextField();
        msgText.setColumns(40);
        msgText.setEditable(false);
        msgText.addActionListener(this);
        startBtn = new JButton("开始");
        startBtn.addActionListener(this);
        sendBtn = new JButton("发送");
        sendBtn.setEnabled(false);
        sendBtn.addActionListener(this);
        showArea = new JTextArea();
        showArea.setEditable(false);
        showArea.setLineWrap(true); //自动换行
        jsp = new JScrollPane(showArea);
        jp1 = new JPanel();
        jp2 = new JPanel();
        jp1.setLayout(new FlowLayout());
        jp2.setLayout(new FlowLayout());
        jp1.add(jl1);
        jp1.add(recPortText);
        jp1.add(jl2);
        jp1.add(sendPortText);
        jp1.add(jl3);
        jp1.add(IPText);
        jp1.add(startBtn);
        jp2.add(msgText);
        jp2.add(sendBtn);
        con = jf.getContentPane();
        con.add(jp1, BorderLayout.NORTH);
        con.add(jsp, BorderLayout.CENTER);
        con.add(jp2, BorderLayout.SOUTH);
        jf.setSize(600, 400);
        jf.setLocation(300, 200);
        jf.setVisible(true);
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    //在线程中接收数据
    public void run() {
        String str;
        while(true){
            try {
                receiveSocket.receive(receivePack);
                str = new String(receivePack.getData(),0,receivePack.getLength());
                showArea.append("对方说:"+str+"\n");
            } catch (IOException e) {
                showArea.append("接收数据出错!\n");
            }
        }

    }

    public void actionPerformed(ActionEvent e) {
        try {
            if(e.getSource()==startBtn){
                inBuf = new byte[BUFSIZE];
                sendPort = Integer.parseInt(sendPortText.getText());
                recPort = Integer.parseInt(recPortText.getText());
                sendIP = InetAddress.getByName(IPText.getText());
                sendSocket = new DatagramSocket();
                //创建接收数据包
                receivePack = new DatagramPacket(inBuf,BUFSIZE);
                //指定接收数据的端口
                receiveSocket = new DatagramSocket(recPort);
                //创建线程准备接收对方的信息
                thread = new Thread(this);
                thread.setPriority(Thread.MIN_PRIORITY);
                thread.start();
                msgText.setEditable(true);
                sendBtn.setEnabled(true);
                startBtn.setEnabled(false);
            }else{ //按下了“发送”按钮或回车键
                outBuf = msgText.getText().getBytes();
                //组装要发送的数据
                sendPack = new DatagramPacket(outBuf,outBuf.length,sendIP,sendPort);
                //发送数据
                sendSocket.send(sendPack);
                showArea.append("我说:"+msgText.getText()+"\n");
                msgText.setText(null);
            }
        } catch (NumberFormatException e1) {
            e1.printStackTrace();
        } catch (UnknownHostException e1) {
            showArea.append("无法连接到指定地址\n");
        } catch (SocketException e1) {
            showArea.append("无法打开指定端口\n");
        } catch (IOException e1) {
            showArea.append("发送数据失败!\n");
        }

    }

    public static void main(String[] args) {
        new UDPchat();

    }
}

4. Java网络编程的新特性(jdk1.7)

4.1 轻量级的HTTP服务

例10. HTTP服务实现的实例。

package Net.http;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.io.*;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
import com.sun.net.httpserver.spi.HttpServerProvider;
public class HTTPServer {

    public static void main(String[] args) throws Exception {
        //通过HttpServerProvider的静态方法provider,获取HttpServerProvider的对象
        HttpServerProvider httpServerProvider = HttpServerProvider.provider();
        //通过InetSocketAddress类,绑定8080作为服务端口
        InetSocketAddress addr = new InetSocketAddress(8088);
        //调用createHttpServer,创建HTTP服务
        HttpServer httpServer = httpServerProvider.createHttpServer(addr, 1);
        //指定HTTP服务的路径
        httpServer.createContext("/myapp/", new MyHttpHandler());
        httpServer.setExecutor(null);
        //启动服务执行
        httpServer.start();
        //输出服务开始的信息
        System.out.println("started");
    }

    static class MyHttpHandler implements HttpHandler {
        //声明抛出异常
        public void handle(HttpExchange httpExchange) throws IOException {
            // 返回客户端的一个字符串
            String response = "This is a simple HTTP Server!";
            // 返回HTTP访问的状态码
            httpExchange.sendResponseHeaders(200, response.length());
            //将返回结果信息输出到客户端
            OutputStream out = httpExchange.getResponseBody();
            out.write(response.getBytes());
            out.close();
        }
    }
}

上述代码是一个可直接运行的Java程序,启动程序运行后,在浏览地址栏中输入访问地址:http://localhost:8088/myapp/,就可以打开页面。

httpExchange.sendResponseHeaders(int code, int length);其中的code是Http响应的返回值,比如404、403、500等。length指的是response的长度,以字节为单位。

5. IPv6网络应用程序的开发

5.1 获取本机IPv6地址

对地址进行过滤,选出确实可用的地址。下述代码实现了这一功能,思路是遍历网络接口的各个地址,直至找到符合要求的地址。

例11. 通过Java程序获取本机的IPv6地址。

package Net.http;
import java.net.*;
import java.util.Enumeration;
import java.io.IOException;

public class GetIPv6Add {
    public static String getLocalIPv6Address() throws IOException{
        InetAddress inetAddress = null;
        //定义一个枚举变量,列出所有的网卡信息
        Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
        outer:
            //遍历所有的网卡,从中找到包含IPv6的地址信息
            while(networkInterfaces.hasMoreElements()){
                Enumeration<InetAddress> inetAds = networkInterfaces.nextElement().getInetAddresses();
                while(inetAds.hasMoreElements()){
                    //判断是否是IPv6地址
                    if(inetAddress instanceof Inet6Address && !isReservedAddr(inetAddress)){
                        break outer;
                    }
                }
            }
        String ipAddr = inetAddress.getHostAddress();
        //过滤掉非地址信息的符号,有些Windows平台上,IP地址的版本信息后面跟着一个%,因而要去掉
        int index = ipAddr.indexOf("%");
        if(index>0){
            ipAddr = ipAddr.substring(0, index);
        }
        return ipAddr;
    }
    /**
     * 过滤本机特殊IP地址
     * @param inetAddr(传入的IP地址作为参数)
     * @return(对传入的IP地址进行判断,返回判断结果
     */
    private static boolean isReservedAddr(InetAddress inetAddr){
        if(inetAddr.isAnyLocalAddress() || inetAddr.isLinkLocalAddress() || inetAddr.isLoopbackAddress()){
            return true;
        }
        return false;
    }

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

    }

}

注意:在windows平台上,取得的IPv6地址后面可能跟了一个百分号加数字。这里的数字是本机网络适配器的编号。这个后缀并不是IPv6标准地址的一部分,可以去除。

时间: 2024-11-05 17:28:38

Java网络编程技术2的相关文章

Java网络编程技术

服务器端网络编程步骤 服务器端的编程步骤和客户端不同,是由四个步骤实现,依次是: 监听端口:服务器端属于被动等待连接,所以服务器端启动以后,不需要发起连接,而只需要监听本地计算机的某个固定端口即可.这个端口就是服务器端开放给客户端的端口,服务器端程序运行的本地计算机的IP地址就是服务器端程序的IP地址. 获得连接:当客户端连接到服务器端时,服务器端就可以获得一个连接,这个连接包含客户端的信息,例如客户端IP地址等等,服务器端和客户端也通过该连接进行数据交换.一般在服务器端编程中,当获得连接时,需

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 { pu

Java网络编程基础【转】

网络编程 网络编程对于很多的初学者来说,都是很向往的一种编程技能,但是很多的初学者却因为很长一段时间无法进入网络编程的大门而放弃了对于该部分技术的学习. 在 学习网络编程以前,很多初学者可能觉得网络编程是比较复杂的系统工程,需要了解很多和网络相关的基础知识,其实这些都不是很必需的.首先来问一个问题:你 会打手机吗?很多人可能说肯定会啊,不就是按按电话号码,拨打电话嘛,很简单的事情啊!其实初学者如果入门网络编程的话也可以做到这么简单! 网络编程就是在两个或两个以上的设备(例如计算机)之间传输数据.

【转】JAVA网络编程基础

转来自己学习用 转自http://www.cnblogs.com/springcsc/archive/2009/12/03/1616413.html 网络编程 网络编程对于很多的初学者来说,都是很向往的一种编程技能,但是很多的初学者却因为很长一段时间无法进入网络编程的大门而放弃了对于该部分技术的学习. 在 学习网络编程以前,很多初学者可能觉得网络编程是比较复杂的系统工程,需要了解很多和网络相关的基础知识,其实这些都不是很必需的.首先来问一个问题:你 会打手机吗?很多人可能说肯定会啊,不就是按按电

java网络编程入门教程

网络编程 网络编程对于很多的初学者来说,都是很向往的一种编程技能,但是很多的初学者却因为很长一段时间无法进入网络编程的大门而放弃了对于该部分技术的学习. 在 学习网络编程以前,很多初学者可能觉得网络编程是比较复杂的系统工程,需要了解很多和网络相关的基础知识,其实这些都不是很必需的.首先来问一个问题:你 会打手机吗?很多人可能说肯定会啊,不就是按按电话号码,拨打电话嘛,很简单的事情啊!其实初学者如果入门网络编程的话也可以做到这么简单! 网络编程就是在两个或两个以上的设备(例如计算机)之间传输数据.

好消息:《Java网络编程核心技术详解》出版

2019年5月从美国回到上海,由于一切都不安定,先在旅馆里宅了4个多月,写完<精通JPA与Hibernate:Java对象持久化技术详解>,就开始写这本书.现在,正是新冠病毒疫情还没结束之际,本书克服种种困难,如期和读者见面了. 我们一不小心,就会被一种潜在的观念暗示:只要忙过了这一阵,将来就能过上高枕无忧的生活.实际上,生活中总是有各种意外的事情发生,小到个人家庭的琐事,大到国家社会的暂时的不安定.为了能随遇而安,就得常常給自己洗脑,不要以为忙过了这一阵,就会有永远太平安宁的出头之日. 戒骄

Java网络编程丶数据库编程丶XML解析技术。

Java网络编程 物理层. 数据链路层. 网络层. 传输层. 会话层. 表示层. 应用层. TCP/IP分层接口包括用于协作层分别完成以下的功能: 网络接口层. 网络互联层. 传输层. 应用层. 套接字: Socket.套接字.是一种抽象层. // 创建客户端Socket向服务器发起连接请求 Socket socket = new Socket("127.0.0.1", 30001); /* 利用已建立的socket创建输入输出流,处理与服务器端的连接 */ // 向服务器写入数据 B

第62节:探索Java中的网络编程技术

前言 感谢! 承蒙关照~ 探索Java中的网络编程技术 网络编程就是io技术和网络技术的结合,网络模型的定义,只要共用网络模型就可以两者连接.网络模型参考. 一座塔有七层,我们需要闯关. 第一层物理层->第二层数据链路层->第三层网络层->第四层传输层->第五层会话层->第六层表示层->第七层应用层. 物理层是主要定义物理设备标准,数据链路层是主要讲从物理层接收的数据进行MAC地址(网卡的地址)的封装与解封装.这层的数据较帧. 网络层是将从下层接收到的数据进行IP地址的

20145311实验四 &quot;Java网络编程及安全&quot;

20145311实验四 "Java网络编程及安全" 程序设计过程 实验内容 ·掌握Socket程序的编写:·掌握密码技术的使用:·设计安全传输系统 ·利用加解密代码包,编译运行代码,一人加密,一人解密:·集成代码,一人加密后通过TCP发送: 实验步骤 在这之前进行了一个socket连接的例子:用百度做了个实验 下面是两人合作进行RSA的加密: 首先建立一个Socket对象,用来连接特定服务器的指定端口(我负责的是服务器端,郑凯杰负责的是客户端,所以也就是输入我这边的ip地址),输入的参