文章目录
1.UDP协议和TCP协议的区别
-
是否需要建立连接通道
UDP协议不需要建立连接通道
TCP协议需要建立连接通道
-
是否是否可靠连接
UDP协议不可靠连接,不太安全,执行效率高
TCP协议是一种可靠连接,安全,执行效率低
-
是否传输文件大小有限制
UDP协议有限制的–>以"数据报包的形式发送",DatagramPacket的方式
TCP协议没有限制–>以"通道的字节流方式"发送
使用字节流的方式来进行通讯 客户端-->获取通道的字节输出流--->写数据 服务端--->获取通道的字节输入流--->读数据
2.UDP协议发送端实现步骤
1)创建发送端的Socker对象
2)创建一个"数据报包"对象
3)使用UDP发送端的Socket对发送"数据报包"
4)释放资源
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
//发送端实现代码
public class UDPSend {
public static void main(String[] args) throws Exception {
//1)创建发送端的Socket对象 :DatagramSocket :此类表示用于发送和接收数据报数据包的套接字。
//构造方法:public DatagramSocket() throws SocketException
DatagramSocket ds = new DatagramSocket() ;
//创建一个"数据报包"对象DatagramPacket
//构造方法:
//public DatagramPacket(byte[] buf, 发送端数据
// int length, 发送的长度
// InetAddress address, ip地址对象
// int port) 端口号
//分步执行
byte[] bytes = "hello,UDP,我来了".getBytes() ; //数据
int length = bytes.length ; //长度
//public static InetAddress getByName(String ho st)
InetAddress inetAddress = InetAddress.getByName("10.12.156.50"); //ip地址对象
int port = 10086 ;
DatagramPacket dp = new DatagramPacket(bytes,length,inetAddress,port) ;
//使用UDP发送端的Socket对发送"数据报包"
//public void send(DatagramPacket p) throws IOException
ds.send(dp) ;
// 4)释放资源
ds.close() ;
}
}
3.UDP协议接收端实现步骤
1)创建接收端的Socker对象
2)创建一个"接收容器"数据报包(数据–>自定义缓冲字节数组 byte[] bytes = new byte[1024]),发送端的数据存储进来
3)接收
4)通过接收端的接收容器:DatagramPacket解析出来的真实数据(数据报包)
5)展示数据
6)释放资源
先运行接收端,然后运行发送端,而且接收端不能运行多次
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
//接收端实现代码
public class UDPReceive {
public static void main(String[] args) throws Exception {
//1)创建接收端的Socket对象
DatagramSocket ds = new DatagramSocket(10086) ;
//2)创建一个"接收容器" 数据报包,将发送端的数据存储进来
//自定义缓冲字节数组
byte[] bytes = new byte[1024] ;
int length = bytes.length ;
DatagramPacket dp = new DatagramPacket(bytes,length) ;
//3)接收
ds.receive(dp); //阻塞式方法
//4)通过接收端的接收容器:DatagramPacket解析出来的真实数据(数据报包)
//public byte[] getData():获取数据报包的缓冲真实数据
byte[] bytes2 = dp.getData();
//public byte[] getData():获取数据报包的缓冲区的真实长度
int length2 = dp.getLength();
//展示数据: 展示ip地址以及内容
String ip = dp.getAddress().getHostAddress() ;
String content = new String(bytes2,0,length2) ;
System.out.println("来自 "+ip+"的数据内容是:"+content);
//释放资源
ds.close();
}
}
4.UDP发送端和接收端的代码实现---->前提 :ip地址对象如何表示!
java.net.InetAddress:此类表示Internet协议(IP)地址
成员方法:
-
public static InetAddress getByName(String host)throws UnknownHostException:
通过主机名称(计算机的全名)或者ip地址的文本(字符串形式),返回值代表的互联网IP地址
-
public String getHostAddress():通过ip地址对象获取ip地址的字符串形式
import java.net.InetAddress;
import java.net.UnknownHostException;
public class InetAddressDemo {
public static void main(String[] args) throws UnknownHostException {
InetAddress inetAddress = InetAddress.getByName("10.12.156.50");
// public String getHostAddress(
String ip = inetAddress.getHostAddress();
System.out.println(ip);//10.12.156.50
//public String getHostName():通过ip地址对象获取主机名称
String hostName = inetAddress.getHostName();
System.out.println(hostName);
}
}
5.使用UDP方式发送端不断的录入数据,接收端不断的去展示示数据
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.*;
/**
* @author Cipher
* @date 2022/2/8 23:12
*
*/
//发送端
public class UDPSend {
public static void main(String[] args) throws IOException {
DatagramSocket ds = new DatagramSocket() ;
BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(System.in));
String flag = null ;
while ((flag = bufferedReader.readLine())!=null) {
if ("886".equals(flag)){
System.out.println("结束本次聊天!");
break ;
}
byte[] bytes = flag.getBytes();
int length = bytes.length;
InetAddress inetAddress = InetAddress.getByName("10.12.156.35");
int port = 1233;
DatagramPacket dp = new DatagramPacket(bytes, length, inetAddress, port);
ds.send(dp);
}
ds.close();
}
}
import java.net.DatagramPacket;
import java.net.DatagramSocket;
/**
* @author Cipher
* @date 2022/2/8 23:13
*/
//接收端
public class UDPReceive {
public static void main(String[] args) throws Exception {
//1)创建接收端的Socket对象
DatagramSocket ds = new DatagramSocket(1233) ;
//2)自定义缓冲字节数组
while (true) {
byte[] bytes = new byte[1024];
int length = bytes.length;
DatagramPacket dp = new DatagramPacket(bytes, length);
//3)接收
ds.receive(dp);
//4)通过接收端的接收容器
byte[] bytes1 = dp.getData();
//int length1 = dp.getLength();
//展示数据:展示ip地址以及内容
String ip = dp.getAddress().getHostAddress();
String content = new String(bytes1,0,length);
System.out.println("从" + ip + ",接收的内容是:" + content);
}
//释放资源
// ds.close();
}
}
6.在一个窗口里既发送,又接收(优化UDP–>使用多线程)
分析:
1)需要分别创建两端的Socket对象(发送端的Socket,和接收的Socket)
2)开启线程:
发送端不断发送消息的线程
及手段不断展示消息的线程
3)创建发送端和及接收端资源类对象
4)创建两个线程
5)启动线程
import java.net.DatagramSocket;
import java.net.SocketException;
/**
* @author Cipher
* @date 2022/2/9 14:30
*/
public class ChatRoomTest {
public static void main(String[] args) {
try {
//需要分别创建两端的Socker对象
DatagramSocket dsSend = new DatagramSocket() ;
DatagramSocket dsReceive = new DatagramSocket(6666);
//创建发送端的资源类对象
SendDemo sd = new SendDemo(dsSend) ;
//创建接收端的资源类对象
ReceiveDemo rs = new ReceiveDemo(dsReceive);
//创建两个线程
Thread t1 = new Thread(sd) ;
Thread t2 = new Thread(rs) ;
//启动线程
t1.start();
t2.start();
} catch (SocketException e) {
e.printStackTrace();
}
}
}
import java.net.DatagramPacket;
import java.net.DatagramSocket;
/**
* @author Cipher
* @date 2022/2/9 14:29
*/
public class ReceiveDemo implements Runnable {
private DatagramSocket ds ;
public ReceiveDemo(DatagramSocket ds){
this.ds = ds;
}
@Override
public void run() {
try {
while (true) {
//创建数据报包,自定义缓冲区大小1024(接收容器)
byte[] buffer = new byte[1024];
int length = buffer.length;
DatagramPacket dp = new DatagramPacket(buffer, length);
//接收
ds.receive(dp);
//解析接收容器中的内容
byte[] bytes = dp.getData();
int len = dp.getLength();
//获取ip地址
String ip = dp.getAddress().getHostAddress();
String content = new String(bytes, 0, len);
//展示内容
System.out.println("data from -->" + ip + "content is:" + content);
}
}catch(Exception e){
e.printStackTrace();
}
}
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
/**
* @author Cipher
* @date 2022/2/9 14:30
*/
public class SendDemo implements Runnable {
private DatagramSocket ds ;
public SendDemo(DatagramSocket ds){
this.ds = ds ;
}
@Override
public void run() {
try {
//不断的键盘录入数据
while(true){
//使用BufferedReader,完成键盘录入
BufferedReader br = new BufferedReader(new InputStreamReader(System.in)) ;
System.out.println("请您输入发送的数据:") ;
String line = br.readLine() ;
//自定义结束条件
if("886".equals(line)){
System.out.println("再见啦!");
break ;
}
//创建数据报包
DatagramPacket dp = new DatagramPacket(
line.getBytes(),
line.getBytes().length,
InetAddress.getByName("10.12.156.35"),
6666) ;
//发送数据报包
ds.send(dp);
}
} catch (IOException e) {
e.printStackTrace();
}
ds.close(); //释放发送端的资源
}
}