今天总结一下,我至今学的第一个网络编程,也是一个最简单的网络编程。

这篇博客只是将如何用代码实现一个网络编程,具体细节不讲解,后续会介绍详细细节。

网络编程会涉及到客户端和服务器的实现。

1.服务器的实现

首先,服务器的接受请求和发送响应的功能,我们通过DatagramSocket类的实例化对象来实现,一般对于服务器,我们一般希望服务器有一个固定的端口号,所以在创建DatagramSocket对象时,一般会固定一个端口号。

接着,我们在一个start方法中具体实现服务器的功能。

首先,我们需要一个UDP数据包来保存客户端发送来的请求,这个UDP数据报可以通过DatagramPacket类来实现

如上图,requestPacket就是来保存客户端发送来的请求,请求的具体内容是保存在构造方法中的byte数组中,注意,此时请求的内容还没有保存到byte数组里面,我们只是构造了一个保存请求内容的载体,还未初始化。 

接着通过socket对象的receive方法来接受客户端发送来的请求

这里receive方法中的requestPacket是一个返回型参数,则经过该方法后,requestPacket的byte数组已经初始换完成了。

注意:当服务器没有接受到客户端发送来的请求时,时会阻塞在receive方法这里的。

接着,接受到客户端发送来的请求之后,我们就要解析请求中的内容。 

 

由于在网络中,数据的发送都是将数据转换为二进制来发送,这里我们就是将二进制还原成字符串。

这里的requestPacket.getData方法是获取保存请求内容的byte数组,而 requestPacket.getLength方法可以获取到byte数组中的有效长度。

再接着,我们就要对请求进行响应,由于,我们这里实现的是回显型服务器,所以请求和响应是相同的,相当于这步骤省略了。

再接着,我们就要将响应返回给客户端,此时,我们也要建立一个UDP数据报来存储响应,不过在建立响应的数据报的时候,由于UDP数据报没有保存对端的ip地址和端口号,所以我们要将目的IP和目的端口号明确,因为服务器返回响应时,我们要明确将响应返回到哪一个客户端。 

接着将响应数据包发送给客户端,也就是返回响应,通过send方法来实现。

最后,我们来打印请求内容和响应内容

getAdress方法用来获取ip地址,getPort方法用来获取端口号。 

服务器完整代码实现

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

public class UdEchoServer {
    //通过socket对象来实现接受请求和发送响应
    DatagramSocket socket=null;
    public UdEchoServer(int port) throws SocketException {
        //port是服务器的固定端口号
        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);

            String request=new String(requestPacket.getData(),0, requestPacket.getLength());

            String response=process(request);

            DatagramPacket responsePacket=new DatagramPacket(response.getBytes(),0,response.getBytes().length
            ,requestPacket.getSocketAddress());

            socket.send(responsePacket);

            System.out.printf("[%s, %d] request: %s, response: %s\n",requestPacket.getAddress().toString(),
                    requestPacket.getPort(),request,response);
        }
    }

    private String process(String request) {
        return request;
    }

    public static void main(String[] args) throws IOException {
        UdEchoServer server=new UdEchoServer(9090);
        server.start();
    }
}

2.客户端的实现

首先,客户端的作用就是向服务器发送请求和接收服务器返回的响应,所以,我们也是要通过DatagramSocket类的实例化对象来实现发送和接受功能。

不过此时数据通过UDP数据报来发送和接收的,而UDP是不保存对端的IP和端口号,所以此时我们可以在客户端的代码中记录服务器的IP和端口号。

还有对于客户端,我们希望客户端的端口号是随机的。

接下来,我们也在一个start方法里面实现客户端中的具体功能。

首先,需要设计一个用户输入请求的功能。

然后再建立一个DatagramPacket对象(UDP数据报)来保存请求的内容,在建立这个UDP数据报时,我们也要明确对端IP和对端的端口号。

InetAddresss.getByName()方法将IP地址转换为。

接着,存储好数据后就要将请求发送给服务器,通过send方法来实现

在接着就要读取服务器的响应,并解析出响应的内容

这一步,我们还要创建一个DatagramPacket对象来保存响应的内容,并通过receive方法来接收服务器的响应和初始化DatagramPacket对象。

最后打印响应的内容 

客户端完整代码

import java.io.IOException;
import java.net.*;
import java.util.Scanner;

public class UdEchoClient {

    DatagramSocket socket=null;

    public String serverIp;//客户端端IP地址
    public int serverPort;//客户端端口号

    public UdEchoClient(String serverIp,int serverPort) throws SocketException {
        this.serverIp=serverIp;
        this.serverPort=serverPort;
        socket=new DatagramSocket();//不传参,会随机分配一个端口号给客户端
    }

    public void start() throws IOException {
        Scanner scanner=new Scanner(System.in);
        while (true){

            System.out.println("请输入你的请求内容");
            String request=scanner.next();

            DatagramPacket requestPacket=new DatagramPacket(request.getBytes(),request.getBytes().length,
                    InetAddress.getByName(serverIp),serverPort);

            socket.send(requestPacket);

            DatagramPacket responsePacket=new DatagramPacket(new byte[4096],4096);
            socket.receive(responsePacket);
            String response=new String(responsePacket.getData(),0,responsePacket.getLength());

            System.out.println(response);

        }
    }

    public static void main(String[] args) throws IOException {
        UdEchoClient client=new UdEchoClient("127.0.0.1",9090);
        client.start();
    }
}

运行代码

 

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐