——- android培训、java培训、期待与您交流! ———-
在进行UDP传输前我们先要了解网络通信规则
网络通信要素:
IP地址:IntetAddr
*网络中的设备标识
*不易记忆,可用主机名
*本地回环地址:127.0.0.1
端口号:
*用于标识逻辑地址,不同进程标识
*有效端口号:0~65535其中0~1024系统使用或保留端口
传输协议:
*通信规则
*TCP/UDP协议
UDP协议特点:
*将数据及源和目的封装数据包中,不需要建立连接
*每个数据报的大小限制在64KB内
*因无连接,是不可靠协议
Socket
*Socket就是为网络服务提供一种机制
*通信两端都有Socket
*网络通信其实就是Socket通信
*数据在两个Socket通过IO传输
DatagramSocket类
此类表示用来发送和接收数据报包的套接字。
数据报套接字是包投递服务的发送或接收点。
从一台机器发送到另一台机器的多个包可能选择不同的路由,也可能按不同的顺序到达。
在 DatagramSocket 上总是启用 UDP 广播发送。
在某些实现中,将 DatagramSocket 绑定到一个更加具体的地址时广播包也可以被接收。
我们通过UDP传输时,只用到两个方法发送包和接收包
示例一:通过UDP协议读取读取键盘输入,并把读到数据打印到控制台上
分析:读取和发送就要建立两个DatagramSocket 一个用于发送另一个用于接收
对于发送端要明确要发送的IP地址以及端口要与接收端一至,否则接收端收不到数据
对于接收端要明确自己的端口,否则收不到数据。
发送端代码:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
public class SendDemo {
/*
* 获取自己的IP地址的代码
*/
// try {
// InetAddress address = InetAddress.getLocalHost();
// System.out.println(address.getHostAddress());
// } catch (UnknownHostException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
/*
* 从键盘上读取数据,并发送
*/
private void sendMessage(){
DatagramSocket dp = null;
try {
dp = new DatagramSocket();
BufferedReader fis = new BufferedReader(new InputStreamReader(System.in));
String message = null;
try {
while((message=fis.readLine())!=null){
System.out.print("请输入:");
if(message.equals("over")){
System.out.println("end");
break;
}
byte []buf = message.getBytes();
/*数据包,对数据进行封装(这个10.40.35.135是我自己的IP地址,
*如果有需要的同学测试时换成自己机器IP地址即可,
*我在这边将端口给固定为8888可更改
*/
DatagramPacket dataPackage = new DatagramPacket(buf, buf.length, InetAddress.getByName("10.40.35.135"), 8888);
try {
dp.send(dataPackage);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
if(dp!=null){
dp.close();
}
}
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
new SendDemo().sendMessage();
}
}
接受端代码:
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class ReceDemo {
/*
* 按收数据
*/
private void udpReceive(){
DatagramSocket dp = null;
try {
//端口号
dp = new DatagramSocket(8888);
while(true){
byte []buf = new byte[1024];
System.out.println("wait send.....................");
DatagramPacket dataPackage = new DatagramPacket(buf, buf.length);
try {
//接收包
dp.receive(dataPackage);
System.out.print(dataPackage.getAddress().getHostAddress()+":");
//解析包
System.out.println(new String(dataPackage.getData(),0,dataPackage.getLength()));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
if(dp!=null){
dp.close();
}
}
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
new ReceDemo().udpReceive();
}
}
示例二:上面写了两个程序每个只负责一个功能,要么收,要么发,
如果我想在发的同时也能收,不是更放便吗?聊天也是这样做的吧!
分析:又要收,又要发只有建立线程才可以完成,一个用于处理收,一个用于处理发,那就需要两个DatagramSocket!
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
/*
* 即可以发又可以收
*/
public class SendAndRece {
static class Rece implements Runnable{
private DatagramSocket dp = null;
public Rece(DatagramSocket dp){
this.dp = dp;
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
System.out.print("please input:");
byte []buf = new byte[1024];
DatagramPacket dataPackage = new DatagramPacket(buf, buf.length);
try {
dp.receive(dataPackage);
//输出
System.out.println(dataPackage.getAddress()+":"+new String(dataPackage.getData(),0,dataPackage.getLength()));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
static class Write implements Runnable{
private DatagramSocket dp = null;
public Write(DatagramSocket dp){
this.dp = dp;
}
@Override
public void run() {
// TODO Auto-generated method stub
String str = null;
BufferedReader fis = new BufferedReader(new InputStreamReader(System.in));
try {
while((str=fis.readLine())!=null){
byte []buf = str.getBytes();
try {
DatagramPacket datagramPacket = new DatagramPacket(buf, buf.length,InetAddress.getByName("10.40.35.135"), 8888);
try {
dp.send(datagramPacket);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//写对象
DatagramSocket dpWrite;
//读对象
DatagramSocket dpRece;
try {
dpWrite = new DatagramSocket();
//指定读的端口
dpRece = new DatagramSocket(8888);
new Thread(new Rece(dpRece)).start();
new Thread(new Write(dpWrite)).start();
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
以上便我本人对UDP通行的理解,示例二我的IP地址是本机地址所以进行本机通信,有兴趣的同学可以把IP地址改成局域网的其他主机,看看是不是能相互通信,感觉是不是很棒!
——- android培训、java培训、期待与您交流! ———-