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标准地址的一部分,可以去除。

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

  1. Java网络编程技术1

    1. Java网络编程常用API 1.1 InetAddress类使用示例 1.1.1根据域名查找IP地址 获取用户通过命令行方式指定的域名,然后通过InetAddress对象来获取该域名对应的IP地 ...

  2. JAVA网络编程【转】出处不详

    网络编程 网络编程对于很多的初学者来说,都是很向往的一种编程技能,但是很多的初学者却因为很长一段时间无法进入网络编程的大门而放弃了对于该部分技术的学习. 在 学习网络编程以前,很多初学者可能觉得网络编 ...

  3. 【转】JAVA 网络编程

    网络编程 网络编程对于很多的初学者来说,都是很向往的一种编程技能,但是很多的初学者却因为很长一段时间无法进入网络编程的大门而放弃了对于该部分技术的学习. 在 学习网络编程以前,很多初学者可能觉得网络编 ...

  4. java网络编程+通讯协议的理解

    参考: http://blog.csdn.net/sunyc1990/article/details/50773014 网络编程对于很多的初学者来说,都是很向往的一种编程技能,但是很多的初学者却因为很 ...

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

    前言 感谢! 承蒙关照~ 探索Java中的网络编程技术 网络编程就是io技术和网络技术的结合,网络模型的定义,只要共用网络模型就可以两者连接.网络模型参考. 一座塔有七层,我们需要闯关. 第一层物理层 ...

  6. 20145205 《Java程序设计》实验报告五:Java网络编程及安全

    20145205 <Java程序设计>实验报告五:Java网络编程及安全 实验要求 1.掌握Socket程序的编写: 2.掌握密码技术的使用: 3.客户端中输入明文,利用DES算法加密,D ...

  7. 20145213《Java程序设计》实验五Java网络编程及安全

    20145213<Java程序设计>实验五Java网络编程及安全 实验内容 1.掌握Socket程序的编写. 2.掌握密码技术的使用. 3.设计安全传输系统. 实验预期 1.客户端与服务器 ...

  8. 20145206《Java程序设计》实验五Java网络编程及安全

    20145206<Java程序设计>实验五 Java网络编程及安全 实验内容 1.掌握Socket程序的编写: 2.掌握密码技术的使用: 3.设计安全传输系统. 实验步骤 我和201451 ...

  9. 20145337实验五Java网络编程及安全

    20145337实验五Java网络编程及安全 实验内容 掌握Socket程序的编写 掌握密码技术的使用 设计安全传输系统 实验步骤 基于Java Socket实现安全传输 基于TCP实现客户端和服务器 ...

随机推荐

  1. 2018年全国多校算法寒假训练营练习比赛(第二场)B - TaoTao要吃鸡

    链接:https://www.nowcoder.com/acm/contest/74/B来源:牛客网 题目描述 Taotao的电脑带不动绝地求生,所以taotao只能去玩pc版的荒野行动了, 和绝地求 ...

  2. JAVAEE——宜立方商城07:Linux上搭建Solr服务、数据库导入索引库、搜索功能的实现

    1. 学习计划 1.Solr服务搭建 2.Solrj使用测试 3.把数据库中的数据导入索引库 4.搜索功能的实现 2. Solr服务搭建 2.1. Solr的环境 Solr是java开发. 需要安装j ...

  3. 解释一下什么是servlet?

    Servlet是一种独立于平台和协议的服务器端的Java技术,可以用来生成动态的Web页面.与传统的CGI(计算机图形接口)和许多其他类似CGI技术相比,Servlet具有更好的可移植性.更强大的功能 ...

  4. python lambda简单介绍

    python lambda 在python中,如果想要创建函数需要使用关键字def,而如果想要创建匿名函数,就需要使用lambda. lambda创建的函数和def创建的函数有什么区别? def创建的 ...

  5. UVA1378 A funny stone game

    博弈论. 就是有一堆石子你拿走一堆中的一个,然后再向后面两堆中加两个问胜负 i<j<=k 所以我们可以直接通过sg函数计算,考虑问题的奇偶性,如果这一位是奇的我们才考虑,偶的可以模仿 然后 ...

  6. BlocksKit(1)-基本类型的分类

    BlocksKit(1)-基本类型的分类 BlocksKit是一个用block的方式来解决我们日常用对集合对象遍历.对象快速生成使用.block作为委托对象的一种综合便利封装库.这个库主要分三个大块C ...

  7. hdu 2112 最短路

    本来是拿来复习一下map的,没想搞了半天,一直wa,最后发现预处理没有处理到所有的点 就是个最短路 Sample Input 6 xiasha westlake xiasha station 60 x ...

  8. vijos 1659 河蟹王国 线段树区间加、区间查询最大值

    河蟹王国 Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 https://vijos.org/p/1659 Description 河蟹王国有一位河蟹国王,他 ...

  9. poj 2623 Sequence Median 堆的灵活运用

    I - Sequence Median Time Limit:1000MS     Memory Limit:1024KB     64bit IO Format:%I64d & %I64u ...

  10. HDU 1269 移动城堡 联通分量 Tarjan

    迷宫城堡 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...