Java UDP Socket

[置顶] Java UDP Socket   .


2013-05-27 16:15 27294人阅读 评论(1) 收藏 举报
.

 

 分类:

TCP/UDP 
.

版权声明:本文为博主原创文章,未经博主允许不得转载。




[java] view plain copy print?
01. 


一. UDP协议定义

UDP协议的全称是用户数据报,在网络中它与TCP协议一样用于处理数据包。在OSI模型中,在第四层——传输层,处于IP协议的上一层。UDP有不提供数据报分组、组装和不能对数据包的排序的缺点,也就是说,当报文发送之后,是无法得知其是否安全完整到达的。

二. 使用UDP的原因
它不属于连接型协议,因而具有资源消耗小,处理速度快的优点,所以通常音频、视频和普通数据在传送时使用UDP较多,因为它们即使偶尔丢失一两个数据包,也不会对接收结果产生太大影响。比如我们聊天用的ICQ和OICQ就是使用的UDP协议。在选择使用协议的时候,选择UDP必须要谨慎。在网络质量令人不十分满意的环境下,UDP协议数据包丢失会比较严重。

三. 在Java中使用UDP协议编程的相关类
1. InetAddress
用于描述和包装一个Internet IP地址。有如下方法返回实例:
getLocalhost():返回封装本地地址的实例。

getAllByName(String host):返回封装Host地址的InetAddress实例数组。

getByName(String host):返回一个封装Host地址的实例。其中,Host可以是域名或者是一个合法的IP地址。
InetAddress.getByAddress(addr):根据地址串返回InetAddress实例。
InetAddress.getByAddress(host, addr):根据主机地符串和地址串返回InetAddress实例。

2. DatagramSocket
用于接收和发送UDP的Socket实例。该类有3个构造函数:
DatagramSocket():通常用于客户端编程,它并没有特定监听的端口,仅仅使用一个临时的。程序会让操作系统分配一个可用的端口。
DatagramSocket(int port):创建实例,并固定监听Port端口的报文。通常用于服务端

DatagramSocket(int port, InetAddress localAddr):这是个非常有用的构建器,当一台机器拥有多于一个IP地址的时候,由它创建的实例仅仅接收来自LocalAddr的报文。
DatagramSocket具有的主要方法如下:
1)receive(DatagramPacket d):接收数据报文到d中。receive方法产生一个“阻塞”。“阻塞”是一个专业名词,它会产生一个内部循环,使程序暂停在这个地方,直到一个条件触发。

2)send(DatagramPacket dp):发送报文dp到目的地。

3)setSoTimeout(int timeout):设置超时时间,单位为毫秒。

4)close():关闭DatagramSocket。在应用程序退出的时候,通常会主动释放资源,关闭Socket,但是由于异常地退出可能造成资源无法回收。所以,应该在程序完成时,主动使用此方法关闭Socket,或在捕获到异常抛出后关闭Socket。

3. DatagramPacket
用于处理报文,它将Byte数组、目标地址、目标端口等数据包装成报文或者将报文拆卸成Byte数组。应用程序在产生数据包是应该注意,TCP/IP规定数据报文大小最多包含65507个,通常主机接收548个字节,但大多数平台能够支持8192字节大小的报文。DatagramPacket类的构建器共有4个:
DatagramPacket(byte[] buf, int length):将数据包中Length长的数据装进Buf数组,一般用来接收客户端发送的数据。
DatagramPacket(byte[] buf, int offset, int length):将数据包中从Offset开始、Length长的数据装进Buf数组。
DatagramPacket(byte[] buf, int length, InetAddress clientAddress, int clientPort):从Buf数组中,取出Length长的数据创建数据包对象,目标是clientAddress地址,clientPort端口,通常用来发送数据给客户端。

DatagramPacket(byte[] buf, int offset, int length, InetAddress clientAddress, int clientPort):从Buf数组中,取出Offset开始的、Length长的数据创建数据包对象,目标是clientAddress地址,clientPort端口,通常用来发送数据给客户端。
主要的方法如下:
1)getData(): 从实例中取得报文的Byte数组编码。
2)setDate(byte[] buf):将byte数组放入要发送的报文中。
四. 实例解析
下面让我们来看一个UDP的服务端和客户端交互通信的例子,在本例中,服务端循环等待客户端发送的信息,并对其进行回应,客户端向服务端发送信息,并接收服务端的回应信息。代码如下:
1.UDP的服务端程序



[java] view plain copy print?
01.import java.io.IOException;   
02.import java.net.DatagramPacket;   
03.import java.net.DatagramSocket;   
04.import java.net.InetAddress;   
05.import java.net.InetSocketAddress;   
06.import java.net.SocketException;   
07.   
08./** 
09. * Copyright 2007 GuangZhou Cotel Co. Ltd. 
10. * All right reserved.     
11. * UTP服务类.      
12. * @author QPING
13. */   
14.public class UdpServerSocket {   
15.    private byte[] buffer = new byte[1024];   
16.       
17.    private DatagramSocket ds = null;   
18.   
19.    private DatagramPacket packet = null;   
20.   
21.    private InetSocketAddress socketAddress = null;   
22.   
23.    private String orgIp;   
24.   
25.    /** 
26.     * 构造函数,绑定主机和端口. 
27.     * @param host 主机 
28.     * @param port 端口 
29.     * @throws Exception 
30.     */   
31.    public UdpServerSocket(String host, int port) throws Exception {   
32.        socketAddress = new InetSocketAddress(host, port);   
33.        ds = new DatagramSocket(socketAddress);   
34.        System.out.println("服务端启动!");   
35.    }   
36.       
37.    public final String getOrgIp() {   
38.        return orgIp;   
39.    }   
40.   
41.    /** 
42.     * 设置超时时间,该方法必须在bind方法之后使用. 
43.     * @param timeout 超时时间 
44.     * @throws Exception 
45.     */   
46.    public final void setSoTimeout(int timeout) throws Exception {   
47.        ds.setSoTimeout(timeout);   
48.    }   
49.   
50.    /** 
51.     * 获得超时时间. 
52.     * @return 返回超时时间. 
53.     * @throws Exception 
54.     */   
55.    public final int getSoTimeout() throws Exception {   
56.        return ds.getSoTimeout();   
57.    }   
58.   
59.    /** 
60.     * 绑定监听地址和端口. 
61.     * @param host 主机IP 
62.     * @param port 端口 
63.     * @throws SocketException 
64.     */   
65.    public final void bind(String host, int port) throws SocketException {   
66.        socketAddress = new InetSocketAddress(host, port);   
67.        ds = new DatagramSocket(socketAddress);   
68.    }   
69.   
70.   
71.    /** 
72.     * 接收数据包,该方法会造成线程阻塞. 
73.     * @return 返回接收的数据串信息 
74.     * @throws IOException  
75.     */   
76.    public final String receive() throws IOException {   
77.        packet = new DatagramPacket(buffer, buffer.length);   
78.        ds.receive(packet);   
79.        orgIp = packet.getAddress().getHostAddress();   
80.        String info = new String(packet.getData(), 0, packet.getLength());   
81.        System.out.println("接收信息:" + info);   
82.        return info;   
83.    }   
84.   
85.    /** 
86.     * 将响应包发送给请求端. 
87.     * @param bytes 回应报文 
88.     * @throws IOException 
89.     */   
90.    public final void response(String info) throws IOException {   
91.        System.out.println("客户端地址 : " + packet.getAddress().getHostAddress()   
92.                + ",端口:" + packet.getPort());   
93.        DatagramPacket dp = new DatagramPacket(buffer, buffer.length, packet   
94.                .getAddress(), packet.getPort());   
95.        dp.setData(info.getBytes());   
96.        ds.send(dp);   
97.    }   
98.   
99.    /** 
100.     * 设置报文的缓冲长度. 
101.     * @param bufsize 缓冲长度 
102.     */   
103.    public final void setLength(int bufsize) {   
104.        packet.setLength(bufsize);   
105.    }   
106.   
107.    /** 
108.     * 获得发送回应的IP地址. 
109.     * @return 返回回应的IP地址 
110.     */   
111.    public final InetAddress getResponseAddress() {   
112.        return packet.getAddress();   
113.    }   
114.   
115.    /** 
116.     * 获得回应的主机的端口. 
117.     * @return 返回回应的主机的端口. 
118.     */   
119.    public final int getResponsePort() {   
120.        return packet.getPort();   
121.    }   
122.   
123.    /** 
124.     * 关闭udp监听口. 
125.     */   
126.    public final void close() {   
127.        try {   
128.            ds.close();   
129.        } catch (Exception ex) {   
130.            ex.printStackTrace();   
131.        }   
132.    }   
133.   
134.    /** 
135.     * 测试方法. 
136.     * @param args 
137.     * @throws Exception 
138.     */   
139.    public static void main(String[] args) throws Exception {   
140.        String serverHost = "127.0.0.1";   
141.        int serverPort = 3344;   
142.        UdpServerSocket udpServerSocket = new UdpServerSocket(serverHost, serverPort);   
143.        while (true) {   
144.            udpServerSocket.receive();   
145.            udpServerSocket.response("你好,sterning!");   
146.               
147.        }   
148.    }   
149.}  



2. UDP客户端程序





[java] view plain copy print?
01.import java.io.*;   
02.import java.net.*;   
03.   
04./** 
05. * Copyright 2007 GuangZhou Cotel Co. Ltd. 
06. * All right reserved.     
07. * UDP客户端程序,用于对服务端发送数据,并接收服务端的回应信息. 
08. * @author QPING
09. */   
10.public class UdpClientSocket {   
11.    private byte[] buffer = new byte[1024];   
12.   
13.    private DatagramSocket ds = null;   
14.   
15.    /** 
16.     * 构造函数,创建UDP客户端 
17.     * @throws Exception 
18.     */   
19.    public UdpClientSocket() throws Exception {   
20.        ds = new DatagramSocket();   
21.    }   
22.       
23.    /** 
24.     * 设置超时时间,该方法必须在bind方法之后使用. 
25.     * @param timeout 超时时间 
26.     * @throws Exception 
27.     */   
28.    public final void setSoTimeout(final int timeout) throws Exception {   
29.        ds.setSoTimeout(timeout);   
30.    }   
31.   
32.    /** 
33.     * 获得超时时间. 
34.     * @return 返回超时时间 
35.     * @throws Exception 
36.     */   
37.    public final int getSoTimeout() throws Exception {   
38.        return ds.getSoTimeout();   
39.    }   
40.   
41.    public final DatagramSocket getSocket() {   
42.        return ds;   
43.    }   
44.   
45.    /** 
46.     * 向指定的服务端发送数据信息. 
47.     * @param host 服务器主机地址 
48.     * @param port 服务端端口 
49.     * @param bytes 发送的数据信息 
50.     * @return 返回构造后俄数据报 
51.     * @throws IOException 
52.     */   
53.    public final DatagramPacket send(final String host, final int port,   
54.            final byte[] bytes) throws IOException {   
55.        DatagramPacket dp = new DatagramPacket(bytes, bytes.length, InetAddress   
56.                .getByName(host), port);   
57.        ds.send(dp);   
58.    



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值