Java网络编程

网络编程
1.在网络通信协议下,实现网络互连的不同计算机上的运行的程序间可以进行数据交换。

网络变成三要素
1.IP地址:每台计算机必须要有唯一标识号。
2.端口:网络的通信本质上是两个应用程序之间的通信,在网络通信时有很多应用程序,而端口号可以看作是应用程序的唯一标识。
3.协议:位于同一网络中进行通信的计算机之间都必须遵守规则,这种规则就是协议。常见协议有UDP,TCP。

IP地址——InetAddress类
1.表示的是一个ip地址对象。
使用静态方法得到该类的对象:static InetAddress getByName(String host) // 参数为主机名,或 字符串类型的IP地址
常用方法:

  1. String getHostName() // 获取此IP地址的主机名。
  2. String getHostAddress() // 返回文本显示中的IP地址字符串。
// 通过InetAddress的静态方法创建对象 
        InetAddress address = InetAddress.getByName("DESKTOP-U1PG1Q4");

        // 获取该对象的主机名
        String hostname = address.getHostName();

        // 获取该对象的IP地址
        String hostAddress = address.getHostAddress();

        System.out.println("hostname: " + hostname);
        System.out.println("hostAddress: " + hostAddress);

端口
1.用两个字节表示的整数。它的取值范围是0~65535。其中,0~1023之间的端口号用于一些知名的网络服务和应用。普通的应用程序需要使用1024以上的端口号,如果一个端口号被另外一个服务或程序所占用,会导致当前程序启动失败。

协议
1.UDP协议:用户数据报协议。它是无连接通信协议。

  1. UDP协议是一种不可靠的协议,它在通信两端都建立一个Socker对象,但是这两个Socker只是发送接收数据的对象。
  2. Java中通过DatagramSocket类来实现UDP的Socket
    发送数据的步骤:
    1.创建发送端的Socket对象。
    2.创建数据并打包。
    3.调用DatagramSocket对象的方法发送数据。
    4.关闭发送端。
DatagramSocket ds = new DatagramSocket();

        // 创建一个数据包对象
        /*DatagramPacket(byte[] buf, int length, InetAddress address, int port)
        构造用于发送长度的分组的数据报包 length指定主机上到指定的端口号。*/
        byte[] buf = "你好!我是发送端!".getBytes();
        int len = buf.length;
        InetAddress address = InetAddress.getByName("192.168.0.101");
        int port = 10000;
        DatagramPacket dp = new DatagramPacket(buf, len, address, port);

        ds.send(dp); // 发送数据包
        ds.close(); // 关闭发送端
  1. 接受数据的步骤:
    1.创建接收端Sorcket对象(DatagramSorckt)。
    2.创建数据包用于接收数据。
    3.调用DatagramSorckt方法接受数据。
    4.解析数据包并在控制台显示。
    5.关闭接收端。
/*DatagramSocket(int port)
        构造数据报套接字并将其绑定到本地主机上的指定端口。*/
        DatagramSocket ds = new DatagramSocket(10000);

        // 创建数据包用于接收数据。
        /*DatagramPacket(byte[] buf, int length)
        构造一个 DatagramPacket用于接收长度的数据包 length 。 */
        byte[] bys = new byte[1024];
        DatagramPacket dp = new DatagramPacket(bys, bys.length);

        ds.receive(dp); // 接受数据

        // 解析数据包并在控制台显示。
        /*byte[] getData() 返回数据缓冲区。  */
        // 获取数据包bys中的所有内容,即使内容并没有把bys填满,该方法也会获取到bys后的空数据
        byte[] buf = dp.getData();
        int length = dp.getLength(); // 获取数据包中的实际长度,去除后面的空数据
        System.out.println(new String(buf, 0, length));

        ds.close();

2.TCP协议:传输控制协议。他是面向连接的通信协议。必须明确发送端和接收端。每次连接都需要三次握手。常用与文件的上传下载等。

三次握手发生在发送数据的准备阶段,保证了连接的可靠性:

  1. 第一次握手:客户端向服务端发出连接请求,等待服务端回应。
  2. 第二次握手:服务端向客户端回送一个响应,通知客户端收到了连接请求。
  3. 第三次握手:客户端再向服务端发送确认信息,确认连接。

原理:TCP协议是一种可靠的协议。它在两端各建立一个Socket对象,从而在通信的两端实现虚拟链路。一旦建立了虚拟的网络链路,两端的程序就可以通过虚拟链路进行通信。

1.Java对TCP协议做了封装,使用Socket对象表示两端的通信端口,并通过Socket产生IO流来进行网络通信。
2.Java为客户端提供了Socket类,为服务端提供了ServerSocket类

TCP发送步骤:

  1. 创建客户端Socket对象。
  2. 创建输出流,写数据。
  3. 释放流资源。
  4. 发送。
// 创建客户端Socket对象
        // Socket(InetAddress address, int port)创建流套接字并将其连接到指定IP地址的指定端口号。
        // Socket s = new Socket(InetAddress.getByName("172.19.172.207"), 12345);

        // Socket(host address, int port)创建流套接字并将其连接到指定IP地址的指定端口号。
        Socket s = new Socket("172.19.172.207", 12345);

        // OutputStream getOutputStream()返回此套接字的输出流。
        OutputStream os = s.getOutputStream();
        os.write("hello...".getBytes());

        s.close();

TCP接收步骤:

  1. 创建服务器端Socket对象(ServerSocket)。
  2. 侦听客户端对象返回一个Socket对象,通过accept() 方法。
  3. 创建输入流读数据,将数据打印在控制台。(这里读数据是通过侦听对象的Socket对象调用getInputStream对象得到的)
  4. 释放流资源。
// ServerSocket(int port)创建绑定到指定端口的服务器套接字。
        ServerSocket ss = new ServerSocket(12345);

        //Socket accept()侦听要连接到此套接字并接受它。
        Socket accept = ss.accept();

        InputStream is = accept.getInputStream();
        byte[] bys = new byte[1024];
        int len = is.read();
        String data = new String(bys, 0, len);
        System.out.println(data);

        ss.close();

TCP四次挥手
原理:在客户端与服务端取消连接时需要四次挥手,这时客户端会发给服务端一个取消连接的请求,服务端收到后回复一个“等一会”的消息,客户端等,服务端发送给客户端可以取消连接的消息,客户端回一个确认取消。(上述“等一会”是指服务端要对即将取消连接的客户端做最后的数据处理)

服务端优化
1.服务器一旦开启不能随意关闭。
2.UUID类,该类回返回一个随机且唯一的名字对象再toString,解决了名字冲突问题。(随机性极大降低重复率,不是绝对的唯一)

// 创建文件名称随机且唯一
        UUID uname = UUID.randomUUID();
        System.out.println(uname.toString());

3.使用多线程,实现服务器与多个客户端进行通信。(这么做的资源消耗太严重,所以创建线程池解决)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值