您的位置:首页 > 编程语言 > Java开发

【Java学习笔记】59:DatagramPack和DatagramSocket做UDP通信

2018-02-13 23:57 856 查看

DatagramPack和DatagramSocket

Socket是基于TCP协议的,先建立连接再进行通信的,还可以基于UDP用户数据报协议不建立连接直接发消息。

DatagramPack
类用于建立Java的UDP数据报对象,其中包含了数据的字节数组,目标主机ip地址和端口号,发送方和接收方的端口号需要一致。

DatagramSocket
类所创建的对象用于发送或接收前面的数据报对象,当使用无参构造器时,这个对象使用
.send(DatagramPack dp)
方法发送数据报对象dp;当使用单参构造器
DatagramSocket(int port)
时,这个对象使用
.receive(DatagramPack dp)
方法接收数据报对象到其参数dp中。为了解析得到的DatagramPack对象dp,可以使用
.getAddress()
获得其来自哪个主机,
.getData()
获取其中的数据的Byte数组,
.getLength()
获得数组的长度。

程序

照着课本敲的。两边是等价的,无分服务端和客户端,所以这种方式逻辑上适合用户之间直接通信。

CentOS上Host1.java

务必
service iptables stop
关闭防火墙,否则收不到数据。

package host1;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Scanner;

//小电脑CentOS上的程序
public class Host1 {

public static void main(String[] args) {
Scanner sc;
Thread readData;// 读取数据单独用一个线程,接收和发送分开
receiveThread rt = new receiveThread();// 线程的目标对象
readData = new Thread(rt);// 创建子线程
readData.start();// 启动子线程,用来接收消息

/* main线程则用来发送消息 */
byte[] buffer = new byte[1];
try {
// 目的主机ip地址
InetAddress ia = InetAddress.getByName("192.168.0.108");
// 构造要发送的数据包(byte数组,数组长度,目的地址,端口号)
DatagramPacket dp = new DatagramPacket(buffer, buffer.length, ia, 3838);
// DatagramSocket类的无参构造器构造的对象用来发送数据包
DatagramSocket ds = new DatagramSocket();
System.out.println(">输入发送给Shelon的数据");
sc = new Scanner(System.in);
while (sc.hasNext())// main线程的阻塞之处
{
String mess = sc.nextLine();// 读入为字符串
if (mess.length() == 0)// 输入为空时结束程序
System.exit(0);
buffer = mess.getBytes("utf-8");// 转换成字节数组,指明编码utf-8
dp.setData(buffer);// 将读入的字节数组存入要发送的数据包
ds.send(dp);// 发送数据包
System.out.println(">输入发送给Shelon的数据");
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

}

}

// 接收数据的线程的目标对象类
class receiveThread implements Runnable {

@Override
public void run() {
DatagramPacket dp;
DatagramSocket ds = null;
byte[] data = new byte[8192];// 用来接收数据包
dp = new DatagramPacket(data, data.length);// 存放接收的数据包
try {
// DatagramSocket类的单参构造器(port)构造的对象用来接收数据包
ds = new DatagramSocket(3838);
} catch (SocketException e) {
e.printStackTrace();
}
while (true) {
// 注意特判上一个异常发生时是null
if (ds == null)
break;
else
try {
// 接收数据到参数DatagramPacket对象中
ds.receive(dp);
// 从这个对象中的Byte数组里拿出来,指明编码是utf-8转成String
String message = new String(dp.getData(), 0, dp.getLength(), "utf-8");
System.out.printf("%25s\n", "收到:" + message);// 前面留25个空
} catch (IOException e) {
e.printStackTrace();
}
}
}

}


Win7上Host2.java

package host2;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Scanner;

//win7电脑上的程序
public class Host2 {

public static void main(String[] args) {
Scanner sc;
Thread readData;// 读取数据单独用一个线程,接收和发送分开
receiveThread rt = new receiveThread();// 线程的目标对象
readData = new Thread(rt);// 创建子线程
readData.start();// 启动子线程,用来接收消息

/* main线程则用来发送消息 */
byte[] buffer = new byte[1];
try {
// 目的主机ip地址
InetAddress ia = InetAddress.getByName("192.168.0.106");
// 构造要发送的数据包(byte数组,数组长度,目的地址,端口号)
DatagramPacket dp = new DatagramPacket(buffer, buffer.length, ia, 3838);
// DatagramSocket类的无参构造器构造的对象用来发送数据包
DatagramSocket ds = new DatagramSocket();
System.out.println(">输入发送给hostlzh的数据");
sc = new Scanner(System.in);
while (sc.hasNext())// main线程的阻塞之处
{
String mess = sc.nextLine();// 读入为字符串
if (mess.length() == 0)// 输入为空时结束程序
System.exit(0);
buffer = mess.getBytes("utf-8");// 转换成字节数组
dp.setData(buffer);// 将读入的字节数组存入要发送的数据包
ds.send(dp);// 发送数据包
System.out.println(">输入发送给hostlzh的数据");
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

}

}

// 接收数据的线程的目标对象类
class receiveThread implements Runnable {

@Override
public void run() {
DatagramPacket dp;
DatagramSocket ds = null;
byte[] data = new byte[8192];// 用来接收数据包
dp = new DatagramPacket(data, data.length);// 存放接收的数据包
try {
// DatagramSocket类的单参构造器(port)构造的对象用来接收数据包
ds = new DatagramSocket(3838);
} catch (SocketException e) {
e.printStackTrace();
}
while (true) {
// 注意特判上一个异常发生时是null
if (ds == null)
break;
else
try {
// 接收数据到参数DatagramPacket对象中
ds.receive(dp);
// 从这个对象中的Byte数组里拿出来
String message = new String(dp.getData(), 0, dp.getLength(), "utf-8");
System.out.printf("%25s\n", "收到:" + message);// 前面留25个空
} catch (IOException e) {
e.printStackTrace();
}
}
}

}


运行结果

CentOS

>输入发送给Shelon的数据
收到:12ok
啊啊啊啊机器学习机器学习
>输入发送给Shelon的数据
刘知昊刘知昊SB
>输入发送给Shelon的数据
收到:我的键盘坏掉了
收到:雪碧透心凉心飞扬


Win7

>输入发送给hostlzh的数据
12ok
>输入发送给hostlzh的数据
收到:啊啊啊啊机器学习机器学习
收到:刘知昊刘知昊SB
我的键盘坏掉了
>输入发送给hostlzh的数据
雪碧透心凉心飞扬
>输入发送给hostlzh的数据
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: