网络编程!

一:服务器

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

public class UdpEchoServer {
    private DatagramSocket socket = null;
    //网络编程的前提是操作网卡,操作网卡是通过socket对象来操作的

    public UdpEchoServer(int port) throws SocketException {
        //服务器程序,要在服务器启动的时候,就把端口号确定下来,
        //因为客户端是主动的一方,服务器是被动的一方,客户端要知道服务器在哪,才能"主动的了"
        /**
         * 实际运行的时候,端口号指定的规则:
         * 1)端口号是合法的:1-65535
         * 2)不能和别的进程的端口号冲突
         */

        socket = new DatagramSocket(port);
    }

    public void start() throws  IOException {
        System.out.println("服务器启动!");
        while (true) {
            // 1) 读取请求并解析
            DatagramPacket requestPacket = new DatagramPacket(new byte[4096], 4096);
            /**
             * 这个PatagramPacket 对象就是一个UDP数据报,包含两个部分
             * 1)报头:通过类的属性来表示的
             * 2)载荷:通过构造方法传递的字符数组,作为持有载荷的空间
             */
            //数组是真正存储数据,持有数据的空间,里面保存了载荷
            //一个DatagramPacket就是一个数据报,但本质上是二进制数据,
            //既然是二进制数据,就可以用字符数据表示
            socket.receive(requestPacket);
            // 为了方便在 java 代码中处理 (尤其是后面进行打印) 可以把上述数据报中的二进制数据, 拿出来, 构造成 String
            String request = new String(requestPacket.getData(), 0, requestPacket.getLength());
            // 2) 根据请求计算响应
            String response = process(request);
            // 3) 把响应写回到客户端
            DatagramPacket responsePacket = new DatagramPacket(response.getBytes(), 0, response.getBytes().length,
                    requestPacket.getSocketAddress());
            //发送的时候,不光有数据,还要有数据要发给谁
            //由于这是UDP,UDP socket自身没有记录对方的IP,端口号 等信息,但 DatagramPacket requestPacket里有
            //getSocketAddress()方法,返回的对象了 就包含了IP ,端口号
            socket.send(responsePacket);

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

    // 由于当前写的是 "回显服务器"
    private String process(String request) {
        return request;
    }

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

二:客户端


import java.net.DatagramSocket;
import java.net.SocketException;

public class UdpEchoClient {
    private DatagramSocket socket = null;
    private String serverIp;
    private int serverPort;

    public UdpEchoClient(String serverIp, int serverPort) throws SocketException {
        socket = new DatagramSocket();
        //客户端,都是需要通过额外的途径知道,服务器,IP, 端口号是什么
        //因此,服务器的IP ,端口号都得是固定的
        // 这俩信息需要额外记录下来, 以备后续使用.
        this.serverIp = serverIp;
        this.serverPort = serverPort;
    }

    public static void main(String[] args) throws SocketException {
        UdpEchoClient client = new UdpEchoClient("127.0.0.1", 9090);
        //服务器和客户端在一个主机上,IP地址就固定写127.0.0.1
        //如果在不同的主机上,服务器IP是啥就写啥
    }
}

在一次通信的过程中,需要知道至少4个核心指标.
1)源IP==>发件人地址
2)源端口号==>发件人电话
3)目的IP==>收件人地址
4)目的端口号==>收件人电话
对于客户端来说,给服务器发送请求,刚才指定的服务器IP,服务器端口号,就是目的IP,目的端口号,源IP,也是客户端所在的IP(127.0.0.1),那么源端口号是什么?
构造Socket对象的时候,没有指定端口号,没指定并不意味着没有,而是操作系统,自动分配了一个空间的(和别的程序不冲突)的端口号,这个自动分配的端口号,每次启动程序都可能不一样.
为什么服务需要有固定的端口号,而客户端就需要让系统自动分配,反过来行不行?
1)服务器要有固定的端口号,是因为,客户端需要主动的服务器发送请求,如果服务器端口号不是固定的,(假设每次都变,此时客户端就不知道请求发给谁了)
2)如果给客户端固定的端口号,是可能和客户端所在的电脑上的其他程序的端口号发生冲突.

二级目录

三级目录

相关推荐

  1. 网络编程!

    2024-04-28 21:06:02       37 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-28 21:06:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-28 21:06:02       100 阅读
  3. 在Django里面运行非项目文件

    2024-04-28 21:06:02       82 阅读
  4. Python语言-面向对象

    2024-04-28 21:06:02       91 阅读

热门阅读

  1. git bash上传本地文件报错debug

    2024-04-28 21:06:02       33 阅读
  2. Scala Extention

    2024-04-28 21:06:02       22 阅读
  3. 使用 GORM 自定义类型:解决问题与技巧分享

    2024-04-28 21:06:02       28 阅读
  4. Mockito Mybatis-plus 单元测试

    2024-04-28 21:06:02       34 阅读
  5. Qt——置灰窗口

    2024-04-28 21:06:02       33 阅读
  6. 官网设计UI设计需要考虑哪些?

    2024-04-28 21:06:02       28 阅读
  7. RTCRTC

    2024-04-28 21:06:02       30 阅读
  8. Unity中的C#事件与回调:一个简单的实例分析

    2024-04-28 21:06:02       36 阅读
  9. Lua语法

    Lua语法

    2024-04-28 21:06:02      27 阅读
  10. Excel常用函数

    2024-04-28 21:06:02       32 阅读
  11. 发布自己的npm包

    2024-04-28 21:06:02       26 阅读
  12. 【VUE】moment.js 时间日期格式化工具

    2024-04-28 21:06:02       33 阅读
  13. vue3 ts table合计样式更改

    2024-04-28 21:06:02       27 阅读