Author:老九
计算机专业
可控之事 沉重冷静 不可控之事 乐观面对
[email protected]
☺️
❓ ❤️ ☕️ ❗️
————————————————
版权声明:本文为CSDN博主「浦上青天」的原创文章
端口号是传输层协议的内容,0-65535的一个整数(占两个字节)
IP地址是一个32位的整数,“点分十进制”
端口号用来标识一个进程,告诉操作系统,当前的这个数据要交给哪一个进程来处理
IP地址+端口号能够标识网络上某一台主机的某一个进程
一个端口号只能被一个进程占用
服务器程序必须关联一个固定的端口号,MySQL默认3306
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
/**
* Description:
* User: 李明浦
* Date: 2022-02-07
* Time: 9:19
*/
public class UDPEchoServer {
//对于一个服务器程序来说,核心流程也要分成两步
//1.进行初始化操作(实例化 socket对象)
//2.进入主循环,接受并处理请求(主循环就是一个“死循环”)
// a)读取数据并解析
// b)根据请求计算响应
// c)把响应结果写回客户端
//需要一个UDP的连接
private DatagramSocket socket = null;
//在构造函数里初始化操作实现连接,并指定端口号
public UDPEchoServer(int port) throws SocketException {
//服务器new socket对象的时候需要和一个ip地址和端口号绑定起来
//如果没有写ip,则默认0.0.0.0(这是一个特殊的ip会关联到这个主机的所有网卡的ip)
//socket对象本身就是一个文件,这个文件就是网卡的抽象
socket = new DatagramSocket(port);
}
public void start() throws IOException {
System.out.println("服务器启动");
while(true)
{
//a)读取请求并解析
//括号里是一个接受数据的缓冲区,需要用户自己手动提供,地址是在接受数据的时候由内存填充
DatagramPacket requestPacket = new DatagramPacket(new byte[4096],4096);
//程序启动会很快到达receive操作,如果客户端没有发送任何数据,此时receive操作会阻塞
//一直到有客户端发送数据过来,当有客户端发送数据过来时候,receive就会将数据保存到DategramPacket对象的缓冲区中
socket.receive(requestPacket);
//把原本请求的数据时byte[]将其转化为String,并且如果发来的数据小于我们缓冲区的大小就会默认添加空格,我们需要去掉无用的空格
String request = new String(requestPacket.getData(),0, requestPacket.getLength()).trim();
//b)根据请求计算响应,处理请求
String response = process(request);
//c)把响应写回给客户端,响应数据就是response,需要包装成一个Packet对象
//这个packet对象要发给谁(目的IP和端口是谁),这两个信息就包含在requestPacket内部了,在调用
//getSocketAddress()方法,就可以获取目的IP和端口了
//response.length()得到的是字符数量,而我们需要的是字节数
DatagramPacket responsePacket = new DatagramPacket(response.getBytes(),response.getBytes().length,requestPacket.getSocketAddress());
socket.send(responsePacket);
//打印一条请求日志
System.out.printf("[%s:%d] req: %s; resp: %s\n",requestPacket.getAddress().toString()
,requestPacket.getPort(),request,response);
}
}
private String process(String request) {
//由于此处是一个echo server,请求内容是啥,响应内容就是啥
//如果是一个更复杂的服务器,此处就需要包含很多的业务逻辑和具体的计算
return request;
}
public static void main(String[] args) throws IOException {
//一个主函数去设置该服务器的端口,并让其开始执行
UDPEchoServer server = new UDPEchoServer(9090);
server.start();
}
}
import java.io.IOException;
import java.net.*;
import java.util.Scanner;
/**
* Description:
* User: 李明浦
* Date: 2022-02-07
* Time: 12:57
*/
public class UDPEchoClient {
//客户端的主要流程分成四步
//1.从用户这里读取输入的数据
//2.构造请求发送给服务器
//3.从服务器读取相应
//4.把响应写回给客户端
private DatagramSocket socket =null;
private String serverIp = null;
private int serverPort = 0;
//启动客户端的时候,指定需要连接哪个服务器
public UDPEchoClient(String serverIp,int serverPort) throws SocketException {
this.serverIp = serverIp;
this.serverPort = serverPort;
//客户端中,创建socket的时候,不需要绑定端口号,由操作系统自动分配一个空闲端口
//一个端口号只能被一个进程绑定
//服务器绑定了端口之后,客户端才能访问
//其次如果客户端绑定了的话,一个主机就只能启动一个客户端了
socket = new DatagramSocket();
}
public void start() throws IOException {
Scanner scanner = new Scanner(System.in);
while(true)
{
//1.读取用户输入数据
System.out.println("输入字符串->");
String request = scanner.nextLine();
if(request.equals("exit"))
{
break;
}
//2.构造请求,发送给服务器
DatagramPacket requestPacket = new DatagramPacket(request.getBytes(),
request.getBytes().length, InetAddress.getByName(serverIp),serverPort);
socket.send(requestPacket);
//3.从服务器读取响应
DatagramPacket responsePacket = new DatagramPacket(new byte[4096],4096);
socket.receive(requestPacket);
String response = new String(requestPacket.getData(),0
,requestPacket.getLength()).trim();
//4.显示响应数据
System.out.println(response);
}
}
public static void main(String[] args) throws IOException {
//此时我们用于自己主机实验,127.0.0.1是一个特殊的ip(环回IP),自己访问自己
//如果服务器和客户端在同一台主机上使用回环ip,如果不在同一台主机上就必须填写服务器的ip
//端口号必须与服务器的端口号一致
// UDPEchoClient client = new UDPEchoClient("127.0.0.1",9090);
UDPEchoClient client = new UDPEchoClient("47.98.116.42",9090);
client.start();
}
}
3.读取请求并解析
客户端
1.先初始化
2.进入主循环
a)读取用户输入
b)构造请求给服务器
服务器
b)根据请求计算响应
c)把响应写给客户端
客户端
c)读取服务器响应
d)把响应写显示到界面上
先赞后看,养成习惯!!!^ _ ^♥♥♥
每天都更新知识点哦!!!
码字不易,大家的支持就是我坚持下去的动力。点赞后不要忘记关注我哦!