1. UDP协议
这里我们首先需要明白一点,UDP本身就是一种不需要连的协议,所以是不存在客户端与服务端的.
我们通常是通过发送方与接收方的概念来区分,但是我们又需要明白一点发送方与接收方可能是同一个机器.
1.1 UDP消息发送1.0
这里我们还是通过代码来讲解,并且这里我们还是分两个部分来讲.
一是发送方,另一个就是接收方
发送方:
代码语言:javascript复制 public static void main(String[] args) throws Exception {
//建立一个DatagramSocket对象,这里同时我们也开放他的6666端口号,只要开放端口号之后就不存在是发送方还是接收方的概念了,既可以是发送方,也可以是接收方.
DatagramSocket socket=new DatagramSocket(6666);
//发送的信息
String msg="你好啊,服务器!";
//发送的对象的ip地址以及端口号
InetAddress localhost=InetAddress.getByName("localhost");
int port=9999;
//发送的数据报的各类信息,数据的起始位置,接收方的ip及端口号
DatagramPacket packet=new DatagramPacket(msg.getBytes(),0,msg.getBytes().length,localhost,port);
//发送数据报
socket.send(packet);
}
接收方:
代码语言:javascript复制public static void main(String[] args) throws Exception{
//开放端口
DatagramSocket socket=new DatagramSocket(9999);
//接收数据报
byte[]buffer=new byte[1024];
DatagramPacket packet=new DatagramPacket(buffer,0,buffer.length);
//阻塞接受将信息存入到packet对象之中
socket.receive(packet);
//打印数据
System.out.println(packet.getAddress().getHostAddress());
System.out.println(new String(packet.getData(),0,packet.getLength()));
//关闭连接
socket.close();
}
其实从上面我们也能够看出来UDP就是不需要连接的,因为整个的过程中我们都没有看到ServerSocket这个对象,而是通过 DatagramSocket 这个对象来进行.
其次就是之前我们都是通过 流的形式 来进行数据的传输,但是在UDP中我们则是通过 数据报 的形式来进行,这里其实如果大家学过计算机网络这门课程的话,应该就懂了.
实际效果:
1.2 UDP消息发送2.0
上面的是我们只能在程序中规定好消息,然后发送,并且整个过程是一次性的,程序执行完就没有了,现在我们编写的就是能够通过键盘输入并且传递信息,并且接收能够持续接受信息,只有当接收到bye这样一个关键字时,我们才退出整个程序.
发送方:
代码语言:javascript复制public static void main(String[] args) throws Exception {
DatagramSocket socket=new DatagramSocket(9999);
while (true){
BufferedReader Reader=new BufferedReader(new InputStreamReader(System.in));
String data= Reader.readLine();
byte [] bytes=data.getBytes();
DatagramPacket packet=new DatagramPacket(bytes,0,bytes.length,new InetSocketAddress("localhost",8888));
socket.send(packet);
if(data.equals("bye"))
break;
}
socket.close();
}
接收方:
代码语言:javascript复制 public static void main(String[] args) throws Exception {
DatagramSocket socket=new DatagramSocket(8888);
while (true){
byte[] bytes=new byte[1024];
DatagramPacket packet=new DatagramPacket(bytes,0,bytes.length);//阻塞式接收包裹
socket.receive(packet);
byte[]newdata=packet.getData();
String data=new String(newdata,0,newdata.length);
System.out.println(data);
if(data.equals("bye"))
break;
}
socket.close();
}
实际效果:
1.3 UDP多线程聊天
这里我们会运用到多线程的理念,如果有不了解的建议先去了解一下之后再来学习.
这里我们主要为发送方与接收方两个角色各创建一个线程
TalkSend
代码语言:javascript复制public class TalkSend implements Runnable {
DatagramSocket socket=null;
BufferedReader Reader=null;
private String toip;
private int fromport;
private int toport;
public TalkSend(String toip, int fromport, int toport) throws Exception {
this.toip = toip;
this.fromport = fromport;
this.toport = toport;
socket=new DatagramSocket(fromport);
Reader=new BufferedReader(new InputStreamReader(System.in));
}
@Override
public void run() {
while (true){
try {
String data= Reader.readLine();
byte [] bytes=data.getBytes();
DatagramPacket packet=new DatagramPacket(bytes,0,bytes.length,new InetSocketAddress(this.toip,this.toport));
socket.send(packet);
if(data.equals("bye"))
break;
}catch (Exception e){
e.printStackTrace();
}
}
socket.close();
}
}
TalkReceive
代码语言:javascript复制public class TalkReceive implements Runnable {
DatagramSocket socket=null;
private String msgfrom;
private int port;
public TalkReceive(String msgfrom,int port) throws SocketException {
this.msgfrom=msgfrom;
this.port = port;
socket=new DatagramSocket(port);
}
@Override
public void run() {
while (true){
try {
byte[] bytes=new byte[1024];
DatagramPacket packet=new DatagramPacket(bytes,0,bytes.length);
socket.receive(packet);
byte[]newdata=packet.getData();
String data=new String(newdata,0,newdata.length);
System.out.println(msgfrom ":" data);
if(data.equals("bye"))
break;
}catch (Exception e){
e.printStackTrace();
}
}
socket.close();
}
}
创建完发送与接收线程之后,我们就可以创建学生与老师两个用户来实现这个聊天程序.
学生:
代码语言:javascript复制public class TalkStudent {
public static void main(String[] args) throws Exception {
new Thread(new TalkSend("localhost",7777,9999)).start();
new Thread(new TalkReceive("老师",8888)).start();
}
}
教师:
代码语言:javascript复制public class TalkTeacher {
public static void main(String[] args) throws Exception {
new Thread(new TalkSend("localhost",5555,8888)).start();
new Thread(new TalkReceive("学生",9999)).start();
}
}
这里我们只需要稍微注意一下端口号的对应就行了
实际效果:
这里出现中文乱码主要是因为cmd是通过GBK来进行编码的,这里可以自己去设置成UTF-8的编码方式.
都看到这儿了,如果觉得对你有帮助的话,可以关注我的公众号,坚持日更技术好文章.