布吉做网站公司,学生管理系统网站,安溪学校网站建设,网络工程专业是什么欢迎各位帅哥美女来捧场#xff0c;本文是介绍UDP网络编程。在这里#xff0c;你会见到最详细的教程#xff1b;细致到每一行代码#xff0c;每一个api的由来和使用它的目的等。 目录
1.UDP相关API
1.1.两个类
1.2.两个类中的方法
2.UDP编程
2.1.大体框架
2.2.内容构… 欢迎各位帅哥美女来捧场本文是介绍UDP网络编程。在这里你会见到最详细的教程细致到每一行代码每一个api的由来和使用它的目的等。 目录
1.UDP相关API
1.1.两个类
1.2.两个类中的方法
2.UDP编程
2.1.大体框架
2.2.内容构造
2.3.方法总结 1.UDP相关API
想要实现UDP编程肯定要掌握一些用来操作udp的api主要两个类多个方法。
1.1.两个类
这两个类包括DatagramSocket和DatagramPacket至于这两个类里面的方法下一个小标题介绍。
1DatagramSocket类
这个类是用来操作网卡的也就是用来创造服务器/客户端。可以获取到操作网卡的一个流对象用来发送数据、接收数据、关闭流对象
2DatagramPacket类
这个类用来表示udp数据报也就是用来保存数据的。DatagramPacket对象可以保存请求、响应、ip/端口号等信息。
1.2.两个类中的方法
1DatagramSocket类
构造方法
方法签名解释DatagramSocket()无参构造。创造一个UDP数据报套接字的Socket绑定到本机任意一个端口一般用于客户端系统会分配一个空闲的端口号DatagramSocket(int port)创造一个UDP数据报套接字的Socket并且绑定到本机指定端口号上一般用于服务器 1无参构造方法一般用在客户端不需要指定端口号这种就是由系统随机分配空闲的端口号。2带参的构造方法一般用在服务器给服务器指定一个端口号服务器需要在启动时就有端口号方便客户端寻找。 普通方法
方法签名说明void receive(DatagramPacket p)从这个套接字接收数据报存到p中如果没接收到会阻塞等待void send(DatagramPacket p)从这个套接字发送数据报p不会阻塞都是直接发送void close()关闭这个数据报套接字类似关闭流 上面三个就是udp通信的三部曲接收请求、解析请求、发送响应服务器发送请求、接收响应客户端最后都需要关闭流一般socket流对象和客户端服务器的声明周期一样就不需要我们去主动关闭 2DatagramPacket类
这是一个描述数据报的类用来保存数据报。
构造方法
方法签名说明DatagramPacket(byte[] bf,int length)构造一个数据报并且使用字节数组接收数据接受指定的长度DatagramPacket(byte[] bf,int offset,int length,SocketAddress address,(port))用来发送数据报。发送的数据在字节数组中从offset到length长度。address包含目的主机的IP和端口号 1第一个构造方法一般用于接收信息像服务器接收请求和客户端接收响应构造一个空的udp数据报对象参数是指定一块存放数据的空间后面的长度表示这一块空间的可用部分。2第二个构造方法一般用于发送信息像服务器发送响应和客户端发送请求构造一个带有信息的udp数据报。具体信息存在第一个参数(请求或者响应)第二、三个参数表示信息的有效长度范围第四个参数里面存放的是ip地址(也可以同时包含端口号)第五个参数表示端口号(当前面一个参数没有包含端口号时)。 普通方法
方法名解释InetAddress getAddress()从接收/发送的数据报中获取发送端的主机IP或者接收端的主机IPint getPort()从接收的数据报中获取发送端主机的端口号或者获取发送端主机的端口号byte[] getData()获取数据报中的数据 这些方法就是用来获取udp数据报中的一些信息的比如第一个获取ip地址第二个获取端口号等不过想要完成udp通信掌握这几个方法还不够但是现在先不介绍完等到介绍完udp通信我们就一起介绍。 2.UDP编程
前置常识接下来就是要编写一个关于udp的网络程序就需要有服务器和客户端两个不同的程序/进程服务器是可以24*7h的处理请求的(我们写成死循环即可)客户端随意(我们也写成死循环表示可以不断发送请求)。
而且我们这里的服务器暂时作为一个回响服务器也就是不解析请求发送什么再发送回去即可。接下来就开始编程我们的第一个简单网络程序吧。 2.1.大体框架
1服务器
//各种包这里先不写
//回显服务器
public class UdpEchoService {private DatagramSocket socket null;public UdpEchoService(int port) throws SocketException {socket new DatagramSocket(port);//给服务器指定端口号}public void start() throws IOException {System.out.println(服务器启动);while(true) {//写成死循环用于不断处理客户端发来的请求//1.接收请求//2.解析请求//3.发送响应(解析好的请求) }}public String service(String request) {//这个方法用来解析请求return request;}public static void main(String[] args) throws IOException {UdpEchoService service new UdpEchoService(1314);service.start();}
}
main方法用来启动服务器会先调用构造方法构造好一个服务器然后里面会自动调用start方法表示服务器真正的启动了(可以处理请求)
2客户端
//各种包这里也暂时不写
public class UdpEchoClient {private DatagramSocket socket null;private String Ip;private int port;public UdpEchoClient(String Ip,int port) throws SocketException {socket new DatagramSocket();//系统随机分配端口号this.Ip Ip;//记录服务器的ip地址this.port port;//记录服务器的端口号}public void start() throws IOException {System.out.println(客户端启动);Scanner in new Scanner(System.in);while (true) {//1.输入请求//2.发送请求//3.接收响应(服务器处理好请求后返回)//4.打印响应 }}public static void main(String[] args) throws IOException {UdpEchoClient client new UdpEchoClient(127.0.0.1,1314);//绑定本主机的服务器client.start();}
}
这里的客户端同理构造方法只是做好了准备工作等到start方法后才能真正的开始发送请求(客户端启动)
2.2.内容构造
1服务器
接下来我们分别完善服务器的三步曲接收请求、解析请求、返回响应。
接收请求
udp客户端发送过来的请求是一个二进制/字节流数据所以我们需要使用一个udp数据报对象来接收也就是构造一个udp数据报对象 DatagramPacket requestPacket new DatagramPacket(new byte[4096],4096);
udp数据报对象中的参数相当于是一个“空盘子”用来接收客户端发送过来的请求udp数据报对象中没有实现就需要我们自己指定一块空间
当udp数据报对象构造完成后就可以开始接收请求了
socket.receive(requestPacket);//接收请求存放在requestPacket中
此时我们就已经拿到客户端的请求了但是此时是二进制信息为了我们方便解析请求所以我们打算将其转换成一个字符串请求
String request new String(requestPacket.getData(),0,requestPacket.getLength());
这里就是需要使用到一些DatagramPacket类的方法了。 1第一个参数前面介绍过多的用来获取udp中的数据2第二、三个参数就是表示要获取udp中信息的范围表示从0到二进制信息结尾getLength()求的是什么长度3最后String有提供相关的构造方法用于将二进制数据转化成字符串数据 完整的接收请求代码
//1.接收请求
DatagramPacket requestPacket new DatagramPacket(new byte[4096],4096);socket.receive(requestPacket);String request new String(requestPacket.getData(),0,requestPacket.getLength());
解析请求
这一步就比较简单了因为是回显服务器只需要发送什么就返回什么即可但是还是要做做样子假装经过方法解析然后得到一个响应。
//2.计算响应
String response service(request);
计算请求的方法
public String service(String request) {return request;
}
这一步很简单
返回响应
我们现在拿到的响应是一个string返回时需要的是一个udp所以也需要转化一下才行我们这里需要使用到上面的udp数据报构造方法
socket.send(responsePacket);
DatagramPacket responsePacket new DatagramPacket(response.getBytes(),0,response.getBytes().length,requestPacket.getSocketAddress());
这里有四个参数需要解释一下 1第一个参数获取到字符串response中的数据2第二、三个参数就是表示需要转化成的udp数据范围3第四个参数从前面接收的请求中获取客户端的ip地址用来服务器确定响应是发给谁的 通过上述的操作此时responsePacket中就包含了响应和信息接下来就可以返回响应了。
socket.send(responsePacket);
服务器的响应代码 public void start() throws IOException {System.out.println(服务器启动);while(true) {//1.接收请求并解析DatagramPacket requestPacket new DatagramPacket(new byte[4096],4096);//构造udp数据报socket.receive(requestPacket);//接收客户端的请求String request new String(requestPacket.getData(),0,requestPacket.getLength());//将二进制请求(udp数据报)转化成字符串(字符流)//2.计算响应String response service(request);//3.返回响应DatagramPacket responsePacket new DatagramPacket(response.getBytes(),0,response.getBytes().length,requestPacket.getSocketAddress());socket.send(responsePacket);System.out.printf([%s:%d] req%s,resp%s\n,requestPacket.getAddress(),requestPacket.getPort(),request,response);// 客户端请求 返回的响应 客户端ip 端口}}public String service(String request) {return request;}
最下面有一个打印客户端信息的代码前面两个就是获取ip地址和端口号的方法 回响服务器完整代码 import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;//回显服务器
public class UdpEchoService {private DatagramSocket socket null;public UdpEchoService(int port) throws SocketException {socket new DatagramSocket(port);//给服务器指定端口号}public void start() throws IOException {System.out.println(服务器启动);while(true) {//1.接收请求并解析DatagramPacket requestPacket new DatagramPacket(new byte[4096],4096);//构造udp数据报socket.receive(requestPacket);//接收客户端的请求String request new String(requestPacket.getData(),0,requestPacket.getLength());//将二进制请求(udp数据报)转化成字符串(字符流)//2.计算响应String response service(request);//3.返回响应DatagramPacket responsePacket new DatagramPacket(response.getBytes(),0,response.getBytes().length,requestPacket.getSocketAddress());socket.send(responsePacket);System.out.printf([%s:%d] req%s,resp%s\n,requestPacket.getAddress(),requestPacket.getPort(),request,response);// 客户端ip 客户端端口号 客户端请求 返回的响应}}public String service(String request) {return request;}public static void main(String[] args) throws IOException {UdpEchoService service new UdpEchoService(1314);System.out.println(我是父类服务器);service.start();}
}
2客户端
现在只需要完成客户端的四部曲即可输入请求、发送请求、接收响应、打印响应
输入请求
我们这里直接使用字符串来接收请求即可
System.out.print(请输入你的请求);
//1.输入请求
String request in.nextLine();
发送请求
因为我们输入的请求是一个字符串类型而发送udp数据报是字节类型也可以说是需要将字符串请求打包成一个udp数据报才能发送
打包请求
DatagramPacket requestPacket new DatagramPacket(request.getBytes(),0,request.getBytes().length,InetAddress.getByName(Ip),port); 这里同理打包成一个DatagramPacket数据报里面需要包含请求和服务器的ip和端口号前面三个参数就不多介绍第四个参数是一个新的方法InetAddress.getByName(int port)用来……
发送请求
socket.send(requestPacket);
发送请求完整代码
//2.发送请求
DatagramPacket requestPacket new DatagramPacket(request.getBytes(),0,request.getBytes().length,InetAddress.getByName(Ip),port);
socket.send(requestPacket);
接收响应
当向服务器发送完请求后就需要接收服务器返回回来的响应类型是一个DatagramPacket数据报。
DatagramPacket responsePacket new DatagramPacket(new byte[4096],4096);
socket.receive(responsePacket);
这里需要提前构造一个DatagramPacket数据报然后再去接收。
打印响应
//4.打印请求
String response new String(responsePacket.getData(),0,responsePacket.getLength());System.out.println(响应为response); 客户端完整代码
//客户端
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.Scanner;public class UdpEchoClient {private DatagramSocket socket null;private String Ip;private int port;public UdpEchoClient(String Ip,int port) throws SocketException {socket new DatagramSocket();this.Ip Ip;this.port port;}public void start() throws IOException {System.out.println(客户端启动);Scanner in new Scanner(System.in);while (true) {System.out.print(请输入你的请求);//1.输入请求String request in.nextLine();//2.发送请求DatagramPacket requestPacket new DatagramPacket(request.getBytes(),0,request.getBytes().length,InetAddress.getByName(Ip),port);socket.send(requestPacket);//3.接收响应DatagramPacket responsePacket new DatagramPacket(new byte[4096],4096);socket.receive(responsePacket);//4.打印请求String response new String(responsePacket.getData(),0,responsePacket.getLength());//System.out.println(中文翻译为response);System.out.println(响应为response);}}public static void main(String[] args) throws IOException {UdpEchoClient client new UdpEchoClient(127.0.0.1,1314);//绑定本主机的服务器client.start();}
}
客户端服务器也就都写好了接下来实验一下。
先启动服务器 在启动客户端 客户端发送请求 服务器日志 至此UDP服务器-客户端编码完成。 执行流程图 2.3.方法总结
在前面我已经介绍过一次方法了现在又准备介绍一次是为了水字数吗那当然不是前面两个类中的一些方法只是为了让你认识到这些类和实例化了对象后该怎么去做。
接下来我们再进一步结合代码来介绍方法而且主要是和DatagramPacket有关的方法。
1获取ip地址和端口号
直接调用方法分别获得
方法解释InetAddress getAddress()获取ip地址int getPort()获取端口号
在代码中的体现 2求数据长度
这里是什么意思呢你一定看过这些代码 这些求数据长度的有什么区别该怎么使用为什么要这样写就是我们接下来要介绍的
字符和字节的区别
首先字符字节一个字符可能包含多个字节。一个字符串如果都是数字或者英文字母那么它的字符数和字节数大概率是一样的但是如果一个字符串中包含汉字等重量字符那么字符数字节数。
求长度的区别
如果本身是一个字节类型的字符串数据那么我们直接取长度就好但是如果是一个String类型的字符串要将它转化成udp数据报就需要先转化成字节类型再求其长度。 如果本身是字节类型就不需要转换如果是字符串类型就需要。原因只要转化成最小单位就不会遗漏数据 3字符串ip地址转成点分十进制格式
在客户端程序里面有这么一个方法 所以通过InetAddress.getByName(String ip)方法就可以将String类型的ip转换成一个java可以识别的ip对象(也就是InetAddress对象)
InetAddress.getByName(String ip)将字符串类型的ip地址转成java可识别的
4同时获得ip地址和端口号
服务器中的一段代码 目的是现在服务器需要将响应发回客户端就需要知道客户端的ip地址和客户端。
getSocketAddress()获取ip和端口号 返回一个InetSocketAddress对象里面就包含ip地址和端口号 5获取数据
获取udp数据报中的数据
byte[] getData()将udp中的数据存入一个字节数组中
代码体现 获取字符串中的数据
byte[] getBytes()将字符串中的数据存入一个字节数组中
代码体现 以上就是udp客户端-服务器编程中使用到的方法了。