提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
目录
udp socket 要掌握的类:
1.DatagramSocket
2.DatagramPacket
一、udp版本回显服务器
服务端:
完整代码
客户端:
完整代码
udp版本翻译服务器:
代码:
udp socket 要掌握的类:
1.DatagramSocket
是UDP Socket,用于发送和接收UDP数据报。(网卡的代言人)
构造方法:
第一种一般用于客户端,第二种一般用于服务器
其他方法:
总结:socket本质上也是文件
socket对应到网卡这个硬件设备,操作系统也是把网卡当做文件来管理的
通过网卡发送数据写文件
通过网卡接受数据读文件
文件操作要先打开文件,然后读文件,最后关闭对应到socket上,构造方法相当于打开,receive,send相当于写,close相当于关闭
2.DatagramPacket
代表一个udp数据报,也就是一次发送接受的基本单位
构造方法
其他方法:
1.绑定端口:
一个端口只能绑定一个进程
2.启动服务器:
3.接受命令:
4.处理响应:
5..响应写会客户端
InetSocketAddress(getAddress(), getPort());
6.打印日志
package net_1011;import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.nio.charset.StandardCharsets;public class UdpEchnoServer {private DatagramSocket socket=null;//参数的端口表示咱的服务器要绑定的端口public UdpEchnoServer(int port) throws SocketException {socket=new DatagramSocket(port);}//通过这个方法启动服务器public void start()throws IOException{System.out.println("服务器启动!");while(true){//循环里面处理一次请求//读取请求并解析DatagramPacket requestPacket=new DatagramPacket(new byte[4096],4096);socket.receive(requestPacket);//把这个DatagramPacket对象转变成字符串,方便去打印String request=new String(requestPacket.getData(),0,requestPacket.getLength());//2.根据请求计算相应String response =process(request);//3.把相应写回到客户端DatagramPacket responsePacket=new DatagramPacket(response.getBytes(),response.getBytes().length,requestPacket.getSocketAddress());socket.send(requestPacket);//4.打印一个日志,记录当前的情况System.out.printf("[%s:%d] req: %s; resp :%s\n",requestPacket.getAddress().toString(),requestPacket.getPort(),request,response);}}//当前写的是一个回显服务器//相应数据和请求数据是一样的public String process(String request) {return request;}public static void main(String[] args) throws IOException {UdpEchnoServer server=new UdpEchnoServer(9090);server.start();}}
1.绑定端口(注意区别)Ip+端口
服务器的ip一般都是本机ip不需要绑定,当涉及多个网卡,多个Ip,访问指定ip地址,服务器才要手动指定ip
2.注意构造方法没有指定参数
//这里并不是说没有端口,而是让系统自动指定一个空闲的端口
系统分配的空闲端口,避免用户乱输入端口,导致影响到进程运行中的端口,
3.注意构造出的数据报是以字节为单位
4.关于DatagramPacket构造的几种方式:
package net_1011;import java.io.IOException;
import java.net.DatagramPacket;
import java.net.SocketException;
import java.net.*;
import java.util.Scanner;public class UdpEchoClient {private DatagramSocket socket=null;private String serverIP;private int serverPort;//俩个参数一会会在发送数据的时候用到//暂时先把这俩参数存起来,以备后用public UdpEchoClient(String serverIP,int serverPort) throws SocketException {//这里并不是说没有端口,而是让系统自动指定一个空闲的端口socket=new DatagramSocket();//假设 serverIP 是形如 1.2.3.4 这种点分十进制的表示方式this.serverIP=serverIP;this.serverPort=serverPort;}public void start() throws IOException {Scanner scanner=new Scanner(System.in);while(true){//1.从控制台读取用户输入的内容System.out.println("-> ");String request=scanner.next();//2.构造一个udp请求,发送给服务器DatagramPacket requstPacket=new DatagramPacket(request.getBytes(),request.getBytes().length,InetAddress.getByName(this.serverIP),this.serverPort);socket.send(requstPacket);//3.从服务器中读取udp响应数据,并解析DatagramPacket responsePacket=new DatagramPacket(new byte[4096],4096);socket.receive(requstPacket);String response=new String(responsePacket.getData(),0,responsePacket.getLength());//4.把服务器的响应显示到控制台上System.out.println(response);}}public static void main(String[] args) throws IOException {UdpEchoClient client=new UdpEchoClient("127.0.0.1",9090);client.start();}
}
总的执行流程:
直观表示:
怎样处理多个请求:
对于服务器来说
读取请求并接续,根据请求并计算相应,把响应写会到客户端执行速度极快,这时候如果有多个客户端发来请求,服务器也是可以响应的。在服务器上本质是三个请求串行处理的
如果处理不过来,采用分布式
package net_1011;import java.io.IOException;
import java.net.SocketException;
import java.util.HashMap;
import java.util.Map;public class UdpTranslateServer extends UdpEchnoServer{//翻译是啥?本质上就是 key ->valueprivate Mapdict=new HashMap<>();public UdpTranslateServer(int port) throws SocketException {super(port);dict.put("cat","小猫");dict.put("dog","小狗");dict.put("fuck","卧槽");//在这里就可以填入很多很多内容,像有道词典程序就这样}//重写process 方法,实现查询哈希表的操作@Overridepublic String process(String request){return dict.getOrDefault(request,"词在词典中未找到");}//start方法和父类完全一样,不用写了public static void main(String[]args) throws IOException{UdpTranslateServer server=new UdpTranslateServer(9090);server.start();}
}