JavaSE 17 网络编程

1、网络的相关概念

网络通信

多台计算机通过一定方式实现数据的传输。

网络

多台计算机之间通过一定的物理设备连接在一起,构成了网络。

分类:【按照网络覆盖范围】
局域网:覆盖范围最小,覆盖一个机房
城域网:覆盖范围较大,覆盖一个城市
广域网:覆盖范围非常大,覆盖全国甚至全球
             互联网就是广域网的一个典型的代表

IP地址

唯一标识网络中的每一台计算机。相当于人的身份证号。

格式:点分十进制
xx.xx.xx.xx

ip地址 = 网络ip + 主机ip
示例:192.168.0.1
每一个十进制数:0~255的范围

分类:

                                     每一个十进制数
A  前一位为网络ip,最后三位为主机ip       0~126
B  前两位为网络ip,最后两位为主机ip      128~191
C  前三位为网络ip,最后一位为主机ip      191~223
D  作为科研、测试
E  作为科研、测试

127.0.0.1 本机回环地址

域名

因为ip地址不好记,所以可以通过域名代表每一台计算机
ip地址和域名有一一映射的关系。

就像通讯录中的号码对应的联系人。
例如:119.75.218.70 www.baidu.com

端口号

标志计算机上的某个网络程序。
范围:0~65535

就像总机 - 分机号
ip - 端口号
例如:tomcat默认8080
           mysql默认3306
           oracle默认1521
           sqlserver默认1433

传输协议

基于TCP的网络传输


Transfer Control Protocol 传输控制协议
类似于打电话

特点:⑴ 传输的数据比较安全、可靠
               有一个三次握手的验证
           ⑵ 没有数据字节的限制
           ⑶ 传输的速度较慢

基于UDP的网络传输

User Datagram Protocol 用户数据报协议
类似于发短信

特点:⑴ 不能保证数据肯定传输到指定的设备
           ⑵ 有数据字节的限制
           ⑶ 传输的速度较快

网络编程

通过一定的方式实现将数据发送到指定的设备上,或接收某个指定设备上的数据。
java.net包下提供了一些列的类,可以帮助程序员做网络编程。

2、InetAddress类

此类表示互联网协议 (IP) 地址。

getLocalHost

public static InetAddress getLocalHost() throws UnknownHostException {}
返回本地主机IP。

getHostName

public String getHostName() {}
获取此 IP 地址的主机名。

getHostAddress

public String getHostAddress() {}
返回 IP 地址字符串(以文本表现形式)。

getByName

public static InetAddress getByName(String host) throws UnknownHostException {}
根据指定主机名,返回对应主机的 IP 地址。

示例

InetAddress localhost = InetAddress.getLocalHost(); // 获取本机IP
System.out.println(localhost);

String hostName = localhost.getHostName(); // 获取主机名
System.out.println(hostName);

System.out.println(localhost.getHostAddress()); // 获取IP地址号

InetAddress address = InetAddress.getByName(hostName); // 根据主机名获取IP
System.out.println(address);

3、Socket类和ServerSocket类

概念

套接字(Stock)允许程序把网络连接当成一个流,数据在连个Stock间通过IO传输。
一般主动发起通讯的应用程序叫客户端,等待通信请求的为服务端。
C/S架构:① 客户端发送请求 ② 服务端接收请求 ③ 服务端给予响应

ServerSocket 表示服务器套接字
Socket 表示客户端套接字(也可以就叫“套接字”)。

ServerSocket

构造方法


public ServerSocket(int port) throws IOException {}
创建绑定到特定端口的服务器套接字。

accept

public Socket accept() throws IOException {}
侦听并接受到此套接字的连接。即接受客户端的连接请求。此方法在连接传入之前一直阻塞。返回一个Socket对象。

Socket

构造方法


public Socket(InetAddress address, int port) throws IOException {}
创建一个流套接字并将其连接到指定 IP 地址的指定端口号。

getOutputStream

public OutputStream getOutputStream() throws IOException {}
返回此套接字的输出流。注意:最好不要使用缓冲流将其包装起来,否则会报错:java.net.SocketException: Socket closed。

getInputStream

public InputStream getInputStream() throws IOException {}
返回此套接字的输入流。其可以用缓冲流包装。

getInetAddress

public InetAddress getInetAddress() {}
返回套接字连接的地址。

shutdownOutput

public void shutdownOutput() throws IOException {}
禁用此套接字的输出流。即设置写入结束标记。对于 TCP 套接字,任何以前写入的数据都将被发送。 如果在套接字上调用 shutdownOutput() 后,继续写入套接字输出流,则该流将抛出 IOException。

使用示例

服务端接收客户端发送的数据

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 服务端
 */
public class TestServer {
  public static void main(String[] args) throws IOException {
    ServerSocket ss = new ServerSocket(10234);
    Socket socket = ss.accept();

    InputStream is = socket.getInputStream();
    BufferedInputStream bis = new BufferedInputStream(is);

    byte[] buffer = new byte[1024];
    int len;
    while (-1 != (len = bis.read(buffer))) {
        System.out.print(new String(buffer, 0, len));
    }

    bis.close();
    socket.close();
    ss.close();
  }
}

import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

/**
 * 客户端
 */
public class TestClient {
  public static void main(String[] args) throws UnknownHostException, IOException {
    Socket socket = new Socket(InetAddress.getLocalHost(), 10234);
    OutputStream os = socket.getOutputStream();
    os.write("这是来自客户端的消息".getBytes());
    os.close();
    socket.close();
  }
}

服务端和客户端互相发送和接收数据

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 服务端
 */
public class TestServer {
  public static void main(String[] args) {
    ServerSocket ss = null;
    Socket socket = null;
    BufferedInputStream bis = null;
    OutputStream os = null;

    try {
      ss = new ServerSocket(10234);
      socket = ss.accept();

      bis = new BufferedInputStream(socket.getInputStream());

      byte[] buffer = new byte[1024];
      int len;
      while (-1 != (len = bis.read(buffer))) {
        System.out.print(new String(buffer, 0, len));
      }

      os = socket.getOutputStream();
      os.write("你好!我是服务端".getBytes());

    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      if (null != os) {
        try {
          os.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
      if (null != bis) {
        try {
          bis.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
      if (null != socket) {
        try {
          socket.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
      if (null != ss) {
        try {
          ss.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }

  }
}

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

/**
 * 客户端
 */
public class TestClient {
  public static void main(String[] args) {
    Socket socket = null;
    OutputStream os = null;
    BufferedInputStream bis = null;

    try {
      socket = new Socket(InetAddress.getLocalHost(), 10234);

      os = socket.getOutputStream();
      os.write("这是来自客户端的消息".getBytes());

      // 不关闭写入结束标记的话,服务端会一直等待客户端发送数据
      // 【java.net.SocketException: Connection reset】
      socket.shutdownOutput();

      bis = new BufferedInputStream(socket.getInputStream());
      byte[] buffer = new byte[1024];
      int len;
      System.out.print(socket.getInetAddress().getHostAddress() + ": ");
      while (-1 != (len = bis.read(buffer))) {
        System.out.print(new String(buffer, 0, len));
      }

    } catch (UnknownHostException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      if (null != bis) {
        try {
          bis.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
      if (null != os) {
        try {
          os.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
      if (null != socket) {
        try {
          socket.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }

  }
}

4、DatagramSocket类和DatagramPacket类

DatagramSocket类表示用来发送和接收数据报包的套接字。在 DatagramSocket 上总是启用 UDP 广播发送。

DatagramPacket类表示数据报包。

DatagramSocket

构造方法


⑴ public DatagramSocket() throws SocketException {}
构造数据报套接字并将其绑定到本地主机上任何可用的端口。多用于创建发送端。

⑵ public DatagramSocket(int port) throws SocketException {}
创建数据报套接字并将其绑定到本地主机上的指定端口。多用于创建接收端。

receive

public synchronized void receive(DatagramPacket p) throws IOException {}
接收数据报包。

send

public void send(DatagramPacket p) throws IOException {}
发送数据报包。

DatagramPacket

构造方法


⑴ public DatagramPacket(byte buf[], int length) {}
构造 DatagramPacket,将接收到的数据,保存到byte数组(缓冲区)中。第二个参数为指定要接收的数据长度。多用于接收端。

⑵ public DatagramPacket(byte buf[], int length, InetAddress address, int port) {}
构造数据报包,用来将长度为length的包,发送到指定主机上的指定端口号。多用于发送端。

getLength

public synchronized int getLength() {}
返回将要发送或接收到的数据的长度。返回值类型为int。

getData

public synchronized byte[] getData() {}
得到实际接收到的数据。返回值类型为byte数组。

使用示例

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

/**
 * 接收端
 */
public class TestReceive {
  public static void main(String[] args) {
    DatagramSocket ds = null;

    try {
      ds = new DatagramSocket(10234);

      byte[] buffer = new byte[1024];
      DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);
      ds.receive(packet);

      byte[] data = packet.getData();
      int len = packet.getLength();
      System.out.println(new String(data, 0, len));

    } catch (SocketException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      if (null != ds) {
        ds.close();
      }
    }

  }
}

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

/**
 * 发送端
 */
public class TestSend {
  public static void main(String[] args) {
    DatagramSocket ds = null;

    try {
      ds = new DatagramSocket();

      byte[] data = "测试文字".getBytes();
      DatagramPacket packet = new DatagramPacket(data, 0, data.length, InetAddress.getLocalHost(), 10234);
      ds.send(packet);

    } catch (SocketException e) {
      e.printStackTrace();
    } catch (UnknownHostException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      if (null != ds) {
        ds.close();
      }
    }

  }
}

5、URL类

URL的概念

Uniform Resource Locator,统一资源定位符,表示Internet上的某一资源的地址。通过URL,我们可以访问Internet上的各种网络资源。比如最常见的www,ftp站点。

URI的概念

Uniform Resource Identifier,统一资源标识符。
URL属于URI的一种。

URL的基本结构

由5部分组成:
       <传输协议>://<主机名>:<端口号>/<文件名>
例如     http : // 192.168.1.1 : 8080 / index.html

构造方法

public URL(String spec) throws MalformedURLException {}
创建URL对象,指向Internet(服务端)上的某一资源。注意:参数需要为完整的绝对路径。

openConnection

public URLConnection openConnection() throws java.io.IOException {}
返回一个 URLConnection 对象,它表示URL所指向的远程对象的连接。

URLConnection类

URLConnection类代表应用程序和 URL 之间的通信链接。此类的实例可用于读取和写入此URL所引用的资源。

getInputStream

public InputStream getInputStream() throws IOException {}
返回从此打开的连接读取的输入流。在读取返回的输入流时,如果在数据可供读取之前达到读入超时时间,则会抛出 SocketTimeoutException。

使用示例【保存某一网络资源】

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

public class TestURL {
  public static void main(String[] args) {
    String srcPath = ""; // 资源路径
    String dest = ""; // 目标路径

    BufferedInputStream bis = null;
    BufferedOutputStream bos = null;

    try {
      URL url = new URL(srcPath);
      URLConnection connection = url.openConnection();

      bis = new BufferedInputStream(connection.getInputStream());
      bos = new BufferedOutputStream(new FileOutputStream(dest));

      byte[] buffer = new byte[1024];
      int len;
      while (-1 != (len = bis.read(buffer))) {
        bos.write(buffer, 0, len);
      }

      } catch (MalformedURLException e) {
        e.printStackTrace();
      } catch (FileNotFoundException e) {
        e.printStackTrace();
      } catch (IOException e) {
        e.printStackTrace();
      } finally {
        if (null != bis) {
          try {
            bis.close();
          } catch (IOException e) {
            e.printStackTrace();
          }
        }
        if (null != bos) {
          try {
            bos.close();
          } catch (IOException e) {
            e.printStackTrace();
          }
        }
      }

  }
}
JavaSE网络编程采用的是基于TCP/IP协议的网络模型。这个模型包括客户端和服务器端两部分。客户端通过套接字(Socket)与服务器建立连接,服务器则监听客户端的连接请求并进行响应。 在Java中,可以使用Socket类和ServerSocket类来实现网络编程。Socket类用于建立客户端与服务器之间的通信连接,而ServerSocket类则用于创建服务器端的套接字,监听并接受客户端的连接请求。 客户端通过创建Socket对象,指定服务器的IP地址和端口号,然后通过Socket对象的方法与服务器进行通信。服务器端通过创建ServerSocket对象,指定服务器要监听的端口号,并通过accept()方法接受客户端的连接请求。一旦建立了连接,客户端和服务器端就可以通过输入流和输出流来进行数据的传输。 网络模型是基于TCP/IP协议的,因此可以使用Java的InputStream和OutputStream来进行数据的读写。客户端可以通过InputStream从服务器端接收数据,通过OutputStream向服务器端发送数据。服务器端则可以通过InputStream接收客户端发送的数据,通过OutputStream向客户端发送数据。 总结来说,JavaSE网络编程采用的是基于TCP/IP协议的网络模型,通过Socket和ServerSocket来实现客户端和服务器端之间的通信。通过InputStream和OutputStream来进行数据的读写。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [JavaSE——网络编程](https://blog.csdn.net/yzl1293346757/article/details/126192384)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [JavaSE学习——网络编程](https://blog.csdn.net/Demon_and_Angle_/article/details/126387829)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值