UDP网络编程
- 1.UDP是面向无连接的数据传输、不可靠的,但传输效率高(传输音频啊、视频啊....)
- 2.UDP一次发送的数据不能超过64KB
- 3.UDP编程所需要的类:
DatagramSocket类的常用方法:
DatagramPacket类的常用方法:
1.public DatagramPacket(byte[] buf,int length,InetAddress address,int port): 用来组装将要发送的数据,第一个参数为
要发送的数据的字节数组信息,第二个参数为字节数组的长度(注意是字节数组的长度,不是发送的数据的长度),第三个
参数是要发送的目的主机的IP地址,第四个参数是发送主机的端口号
2.public DatagramPacket(byte[] buf,int length): 这个构造方法是用来接受发送方的数据,用一个字节数组来承放,另一个
参数意思是字节数组的长度,
3.public InetAddress getAddress(): 在获取到接受到的数据报包后,调用该方法获得发送方的IP地址;
4.public byte[] getData(): 返回将要发送的数据的字节数组,或者接受到的数据字节数组
5.public int getLength(): 返回将要发送的数据字节长度或者接收到的数据长度
基于UDP协议的Socket编程
1.创建发送端
a). 建立DatagramSocket对象,该端点建立,可以手动指定端口号。
b).将数据进行packet包的封装,必须要指定目的地址和端口号信息;
c). 通过socket服务的send方法将该包中发出
d).将socket关闭。
2.创建接受端
a).建立DatagramSocket对象,监听一个端口
b).通过socket的receive()方法将数据存入数据包中
c).通过数据包dp的方法getData()、getAddress()、getPort()等方法获得发送放的一些信息
d).将socket关闭
接下来看一个基于UDP的通信的例子:
发送方:
package udpsocket;
import java.net.*;
public class SendSocet {
public static void main(String[] args) {
DatagramSocket ds = null;
DatagramPacket dp = null;
try {
ds = new DatagramSocket(8888); //设置发送方的端口地址
//System.out.println("等待用户连接。。。");
String str = "我是你爸爸。。。"; //输入将要发送的信息
dp = new DatagramPacket(str.getBytes(),str.getBytes().length,
InetAddress.getByName("localhost"),6666); //将需要发送的信息加以组装
ds.send(dp); //将组装好的信息发送给接收方
System.out.println("发送成功。。。。");
} catch (Exception e) {
e.printStackTrace();
}
}
}
接受数据方:
package udpsocket;
import java.net.*;
public class ReceiveSocket {
public static void main(String[] args) {
DatagramSocket ds = null;
DatagramPacket dp = null;
try {
ds = new DatagramSocket(6666); //设置接收方的端口号
System.out.println("等待数据发送。。。");
//组装接收到的信息
byte[] b = new byte[1024];
dp = new DatagramPacket(b,b.length);
System.out.print("接收到的信息为:");
ds.receive(dp); //用来接收发送方的发送来的数据,未接收到之前会一直阻塞
byte[] data = dp.getData();
System.out.println(new String(data,0,dp.getLength()));
} catch (Exception e) {
e.printStackTrace();
}
}
}
接收方在接收到数据之前会一直处于阻塞状态,具体如下:
package chat;
import java.io.*;
import java.net.*;
public class SendRunnable implements Runnable{
private DatagramSocket ds; //ds由客户端决定
private String destHost; //由客户端决定目的IP
private int port; //由客户端决定目标端口
public SendRunnable(DatagramSocket ds,String destHost,int port){
this.ds = ds;
this.destHost = destHost;
this.port = port;
}
public void run(){
BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); //接收键盘输入
DatagramPacket dp = null;
try {
//写一个死循环实现两端的不断通话
while(true){
System.out.print("我说:");
String say = br.readLine(); //获取键盘输入的内容
dp = new DatagramPacket(say.getBytes(),say.getBytes().length,
InetAddress.getByName(destHost),port); //将键盘输入内容组成数据包发送给目标ip
ds.send(dp); //发送数据包
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
接收方的接受线程:
package chat;
import java.io.IOException;
import java.net.*;
public class ReceiveRunnable implements Runnable{
private DatagramSocket ds; //用来接收发送方发送的数据
public ReceiveRunnable(DatagramSocket ds){
this.ds = ds;
}
//接收用户数据的线程
public void run(){
try {
while(true){
// System.out.println();
DatagramPacket dp = null;
//定义承接发送方发送的数据的字节数组
byte[] b = new byte[1024];
dp = new DatagramPacket(b,b.length);
ds.receive(dp); //接收发送的内容
System.out.println();
System.out.println(dp.getAddress().getHostName()+":"+dp.getPort()+"说:"
+new String(dp.getData(),0,dp.getLength())); //输出那个主机IP+端口号发送的消息
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
写两个通信双方类:
package chat;
import java.net.DatagramSocket;
import java.net.SocketException;
public class ChatA {
public static void main(String[] args) {
try {
DatagramSocket ds = new DatagramSocket(6666);
new Thread(new SendRunnable(ds, "localhost",8888)).start();
new Thread(new ReceiveRunnable(ds)).start();
} catch (SocketException e) {
e.printStackTrace();
}
}
}
package chat;
import java.net.DatagramSocket;
import java.net.SocketException;
public class ChatB {
public static void main(String[] args) {
try {
DatagramSocket ds = new DatagramSocket(8888);
new Thread(new SendRunnable(ds, "localhost",6666)).start();
new Thread(new ReceiveRunnable(ds)).start();
} catch (SocketException e) {
e.printStackTrace();
}
}
}
看一下双方通信的结果吧: