Java中的网络编程如何理解——精简_怎么理解java的网络信息技术

注册端口:1024-49151,分配给用户进程或某些应用程序。(如:Tomcat占用8080,MySQL占用3306)。

动态端口:49152-65535,之所以称为动态端口,是因为它一般不固定分配某种进程,而是动态分配。

**注意:**我们自己开发的程序选择注册端口,且一个设备中不能出现两个程序的端口号一样,否则出错。

协议

传输层的两个常见协议:

  • TCP:传输控制协议
  • UDP:用户数据协议

TCP协议特点:

  • 使用TCP协议,必须双方先建立连接,它是一种面向连接的可靠通信协议
  • 传输前,采用“三次握手”方式建立连接,所以是可靠的
  • 在连接中可进行大数据量的传输
  • 连接、发送数据都需要确认,且传输完毕后,还需释放已建立的连接,通信效率较低

TCP协议通信场景:

  • 对信息安全要求较高的场景,如:文件下载、金融等数据通信

UDP协议:

  • UDP是一种无连接、不可靠传输的协议
  • 将数据源IP、目的地IP和端口封装成数据包,不需要建立连接
  • 每个数据包的大小限制在64KB内
  • 发送不管对方是否准备好,接收方收到也不确认,故是不可靠的
  • 可以广播发送,发送数据结束时无需释放资源,开销小,速度快

UDP协议通信场景:

语言通话、视频通话等。

UDP通信

DatagramPacket:数据包对象

构造器说明
public DatagramPacket(byte[ ]buf,int length,InetAddress address,int port)创建发送端数据包对象 buf:要发送的内容,字节数组 length:要发送内容的字节长度 address:接收端的 IP地址对象 port:接收端的端口号
public DatagramPacket(byte [ ] buf, int length  )创建接收端的数据包对象 buf:用来存储接收的内容 length:能够接收内容的长度

DatagramSocket:发送端和接收端对象

构造器说明
public DatagramSocket( )创建发送端的socket对象,系统会随机分配一个端口号
public DatagramSocket(int port)创建接收端的socket对象并指定端口号
方法说明
public void send (DatagramPacket dp)发送数据包
public void receive (DatagramPacket p)接收数据包

为了更好的理解DatagramSocket和DatagramPacket,我们可以形象的把UDP形象的想象成“网购”,其中DatagramPacket就代表我们想要网购的商品,虽然这是我们买的,但是我们肯定是没有办法亲自去把商品拿走,因此就需要快递的运送,而DatagramSocket就是充当这个角色。商家将需要邮寄的商品通过DatagramPacket封装起来,然后再通过快递DatagramSocket将该商品派送到买家的手中。

//客户端
public static void main(String[] args) throws Exception{
        DatagramSocket socket = new DatagramSocket();
        byte [] buffer = "你好,我是石原里美!".getBytes();
        DatagramPacket packet = new DatagramPacket(buffer,buffer.length, InetAddress.getLocalHost(),9999);
        socket.send(packet);
        socket.close();
    }
//服务端
public static void main(String[] args) throws Exception{
        DatagramSocket socket = new DatagramSocket(9999);
        byte[] buffer = new byte[1024];
        DatagramPacket packet = new DatagramPacket(buffer,buffer.length);
        socket.receive(packet);
        int len = packet.getLength();//返回获取数据的长度
        String s = new String(buffer,0,len);
        System.out.println(s);
        socket.close();
    }

注意:服务端需要先启动,等待客户端向服务端传送数据。

TCP通信

Socket

构造器说明
public Socket(String host , int port)创建发送端的Socket对象与服务端连接,参数为服务端程序的ip和端口。
方法说明
OutputStream getOutputStream( )获得字节输出流对象
InputStream getInputStream()获得字节输入流对象

ServerSocket(服务端)

构造器说明
public ServerSocket(int port)注册服务端端口
方法说明
public Socket accept()等待接口客户端的Socket通信连接,连接成功返回Socket对象与客户端建立端与端通信
//客户端
public static void main(String[] args) throws Exception{
        Socket socket = new Socket("172.0.0.1",7777);
        OutputStream os = socket.getOutputStream();
        //通过打印输入流可以更高效
        PrintStream printStream = new PrintStream(os);
        printStream.println("你好,我是石原里美!");
        printStream.flush();
        }
    }
public static void main(String[] args) throws  Exception{
        ServerSocket serverSocket = new ServerSocket(7777);
        Socket socket = serverSocket.accept();
        InputStream is = socket.getInputStream();
        //将字节输入流转化位字符输入流,再封装位缓冲字符输入流
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(is));
        String s ;
        while ((s = bufferedReader.readLine())!=null){
            System.out.println(socket.getLocalSocketAddress()+s);
        }
    }

实现同时接收多个客户端

如果想要实现同时接收多个客户端的话,就需要使用多线程的知识,创建多个服务端。

首先创建一个类继承Thread,用于创建多线程:

public class ServerThread extends Thread{
    private Socket socket;

    public ServerThread(Socket socket) {
        this.socket = socket;
    }
//中间内容不在此赘述

    @Override
    public void run() {
        try {
            InputStream is = socket.getInputStream();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(is));
            String s ;
            while ((s = bufferedReader.readLine())!=null){
                System.out.println(socket.getLocalSocketAddress()+s);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

客户端代码:

public static void main(String[] args) throws Exception{
        Socket socket = new Socket("172.0.0.1",7777);
        OutputStream os = socket.getOutputStream();
        PrintStream printStream = new PrintStream(os);
        Scanner sc = new Scanner(System.in);
        while (true) {
            String s = sc.next();
            printStream.println(s);
            printStream.flush();
        }
    }

服务端代码:

public static void main(String[] args) throws  Exception{
        ServerSocket serverSocket = new ServerSocket(7777);
        while (true) {
            Socket socket = serverSocket.accept();
            new ServerThread(socket).start();
        }

    }

具体操作:在运行单个服务端代码之后,运行多个客户端代码即可实现同时接收多个客户端。

线程池优化

通过前面的知识,我们了解到每一次都创建一个线程会影响系统的效率,因此需要通过线程池来控制线程的数量,若对线程池不理解的可以看这篇文章:

Java中的多线程如何理解

相对之前需要将线程类更改一下,需要写一个实现Runnable接口的线程类。

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

[外链图片转存中…(img-gilXySUt-1714236212957)]
[外链图片转存中…(img-cPmn0kjt-1714236212957)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值