提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
目录
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 ->value
private Mapdict=new HashMap<>();
public UdpTranslateServer(int port) throws SocketException {
super(port);
dict.put("cat","小猫");
dict.put("dog","小狗");
dict.put("fuck","卧槽");
//在这里就可以填入很多很多内容,像有道词典程序就这样
}
//重写process 方法,实现查询哈希表的操作
@Override
public String process(String request){
return dict.getOrDefault(request,"词在词典中未找到");
}
//start方法和父类完全一样,不用写了
public static void main(String[]args) throws IOException{
UdpTranslateServer server=new UdpTranslateServer(9090);
server.start();
}
}