ToB企服应用市场:ToB评测及商务社交产业平台

标题: java 网络编程 [打印本页]

作者: 十念    时间: 2023-8-30 12:11
标题: java 网络编程
网络编程

一、概述

网络编程是指编写运行在多个设备(计算机)的程序,这些设备都通过网络连接起来。
计算机网络

把分布在不同地理区域的计算机与专门的外部设备用通信线路互连成一个规模大,功能强的网络系统, 从而使众多的计算机可以方便地互相传递信息,共享硬件,软件,数据信息等资源。
网络编程目的

网络编程中主要问题

二、网络通信要素

IP

例如:
  1. 192.168.10.102
复制代码
端口号

端口号与IP地址的组合,得出一个网络套接字:Socket,所以说一些网络编程也被称为Socket编程
通信协议

说协议前需要了解网络体系结构。
网络体系结构

以前是OSI参考模型,但由于模型过于理想化,未能在因特网上进行广泛推广。现在国际上的标准是 TCP/IP 参考模型。
网络体系结构:

而网络通信主要在 传输层。所以需要了解的通信协议也就是:TCP 与 UDP
TCP

UDP

三、TCP网络编程

1、通过上述可知,网络编程也可为 socket 编程;而 socket 是套接字。即将 端口号拼接到 ip 地址构成的。
2、套接字使用TCP提供了两台计算机之间的通信机制。 客户端程序创建一个套接字,并尝试连接服务器的套接字。当连接建立时,服务器会创建一个 Socket 对象。客户端和服务器现在可以通过对 Socket 对象的写入和读取来进行通信。java.net.Socket 类代表一个套接字,并且 java.net.ServerSocket 类为服务器程序提供了一种来监听客户端,并与他们建立连接的机制。
3、通过如下步骤即可在两台计算机之间使用套接字建立 TCP 连接:
当连接建立后,即可通过 I/O 流进行通信。
在 java 中提供了一个类用于获取一个端口,并且侦听客户端请求。如下
ServerSocket 类

服务器应用程序通过使用 java.net.ServerSocket 类以获取一个端口,并且侦听客户端请求。
构造方法如下:
  1. public ServerSocket()        //创建非绑定服务器套接字
  2. public ServerSocket(int port)        //创建绑定到特定端口的服务器套接字。
  3. public ServerSocket(int port, int backlog)        //利用指定的 backlog 创建服务器套接字并将其绑定到指定的本地端口号。
  4. public ServerSocket(int port, int backlog, InetAddress bindAddr)        //使用指定的端口、侦听 backlog 和要绑定到的本地 IP 地址创建服务器。
复制代码
常用方法:
  1. public int getLocalPort()        //返回此套接字在其上侦听的端口。
  2. public Socket accept()                 //侦听并接受到此套接字的连接。
  3. public void setSoTimeout(int timeout)                //通过指定超时值启用/禁用 SO_TIMEOUT,以毫秒为单位
  4. public void bind(SocketAddress host, int backlog)                //将 ServerSocket 绑定到特定地址(IP 地址和端口号)。
复制代码
Socket 类

java.net.Socket 类代表客户端和服务器都用来互相沟通的套接字。客户端要获取一个 Socket 对象通过实例化 ,
而 服务器获得一个 Socket 对象则通过 accept() 方法的返回值。
构造方法:
  1. public Socket(String host, int port)                //创建一个流套接字并将其连接到指定主机上的指定端口号。
  2. public Socket(InetAddress host, int port)        //创建一个流套接字并将其连接到指定 IP 地址的指定端口号
  3. public Socket(String host, int port, InetAddress localAddress, int localPort)        //创建一个套接字并将其连接到指定远程主机上的指定远程端口。
  4. public Socket(InetAddress host, int port, InetAddress localAddress, int localPort) //创建一个套接字并将其连接到指定远程地址上的指定远程端口
  5. public Socket()                //通过系统默认类型的 SocketImpl 创建未连接套接字
复制代码
常用方法:
  1. public void connect(SocketAddress host, int timeout)         //将此套接字连接到服务器,并指定一个超时值。
  2. public InetAddress getInetAddress()                                                //返回套接字连接的地址。
  3. public int getPort()                                                                //返回此套接字连接到的远程端口。
  4. public int getLocalPort()                                                        //返回此套接字绑定到的本地端口。
  5. public SocketAddress getRemoteSocketAddress()        //返回此套接字连接的端点的地址,如果未连接则返回 null。
  6. public InputStream getInputStream()                 //返回此套接字的输入流。
  7. public OutputStream getOutputStream()                 //返回此套接字的输出流。
  8. public void close()                         //关闭此套接字。
复制代码
注意:客户端和服务器端都有一个 Socket 对象,所以无论客户端还是服务端都能够调用这些方法。
InetAddress 类

这个类表示互联网协议(IP)地址。类中是没有构造方法的,所以不能 new 。而可以通过如下方法来进行获取 ip 地址
  1. static InetAddress getByAddress(byte[] addr)                //在给定原始 IP 地址的情况下,返回 InetAddress 对象。
  2. static InetAddress getByAddress(String host, byte[] addr)                //根据提供的主机名和 IP 地址创建 InetAddress。
  3. static InetAddress getByName(String host)                //在给定主机名的情况下确定主机的 IP 地址。
  4. String getHostAddress()                 //返回 IP 地址字符串(以文本表现形式)。
  5. String getHostName()                 //获取此 IP 地址的主机名。
  6. static InetAddress getLocalHost()                //返回本地主机。
  7. String toString()                //将此 IP 地址转换为 String。
复制代码
案例一:TCP 通信

服务端:
  1. public class TcpServer {
  2.     public static void main(String[] args) {
  3.         ByteArrayOutputStream bos = null;
  4.         InputStream is = null;
  5.         Socket socket = null;
  6.         ServerSocket serverSocket = null;
  7.         try {
  8.             //1、设置服务端的地址与端口
  9.             serverSocket = new ServerSocket(9923);
  10.             //2、监听该端口的请求
  11.             socket = serverSocket.accept();
  12.             //3、读取信息,通过管道流
  13.             //获取输入流
  14.             is = socket.getInputStream();
  15.             //获取字节缓冲数组流,用于输出
  16.             bos = new ByteArrayOutputStream();
  17.             //设置缓冲数组
  18.             byte[] buffer = new byte[1024];
  19.             int len;
  20.             while ((len = is.read(buffer)) != -1){
  21.                 bos.write(buffer, 0, len);
  22.             }
  23.             System.out.println(bos.toString());
  24.         } catch (IOException e) {
  25.             e.printStackTrace();
  26.         }finally {
  27.             //4、资源关闭
  28.             if (null != bos) {
  29.                 try {
  30.                     bos.close();
  31.                 } catch (IOException e) {
  32.                     e.printStackTrace();
  33.                 }
  34.             }
  35.             if (null != is) {
  36.                 try {
  37.                     is.close();
  38.                 } catch (IOException e) {
  39.                     e.printStackTrace();
  40.                 }
  41.             }
  42.             if (null != socket) {
  43.                 try {
  44.                     socket.close();
  45.                 } catch (IOException e) {
  46.                     e.printStackTrace();
  47.                 }
  48.             }
  49.             if (null != serverSocket) {
  50.                 try {
  51.                     serverSocket.close();
  52.                 } catch (IOException e) {
  53.                     e.printStackTrace();
  54.                 }
  55.             }
  56.         }
  57.     }
  58. }
复制代码
客户端:
  1. public class TcpClient {
  2.     public static void main(String[] args) {
  3.         OutputStream outputStream = null;
  4.         Socket socket = null;
  5.         try {
  6.             //1、设置ip地址
  7.             InetAddress inetAddress = InetAddress.getByName("127.0.0.1");
  8.             //2、设置端口
  9.             int port = 9923;
  10.             //3、创建交流的套子接口
  11.             socket = new Socket(inetAddress, port);
  12.             //4、进行交流
  13.             outputStream = socket.getOutputStream();
  14.             outputStream.write("你好,java网络编程".getBytes());
  15.         } catch (Exception e) {
  16.             e.printStackTrace();
  17.         }finally {
  18.             //5、进行资源关闭
  19.             if (null != outputStream) {
  20.                 try {
  21.                     outputStream.close();
  22.                 } catch (IOException e) {
  23.                     e.printStackTrace();
  24.                 }
  25.             }
  26.             if (null != socket) {
  27.                 try {
  28.                     socket.close();
  29.                 } catch (IOException e) {
  30.                     e.printStackTrace();
  31.                 }
  32.             }
  33.         }
  34.     }
  35. }
复制代码
案例二:TCP 文件

服务端:
  1. public class TcpFileServer {
  2.     public static void main(String[] args) throws Exception {
  3.         //1、设置端口
  4.         ServerSocket serverSocket = new ServerSocket(9923);
  5.         //2、监听端口
  6.         Socket socket = serverSocket.accept();
  7.         //3、获取客户端发送的数据
  8.         InputStream inputStream = socket.getInputStream();
  9.         //将数据写入该路径下的文件
  10.         //FileOutputStream fileOutputStream = new FileOutputStream(new File("reseve.txt"));
  11.         FileOutputStream fileOutputStream = new FileOutputStream(new File("/opt/software/reseve.txt"));//虚拟机地址
  12.         byte[] buffer = new byte[1024];
  13.         int len;
  14.         while ((len = inputStream.read(buffer)) != -1){
  15.             fileOutputStream.write(buffer, 0, len);
  16.         }
  17.         //4、通知客户端传输完毕
  18.         OutputStream outputStream = socket.getOutputStream();
  19.         outputStream.write("已接收完毕".getBytes());
  20.         //5、关闭资源
  21.         outputStream.close();
  22.         fileOutputStream.close();
  23.         inputStream.close();
  24.         socket.close();
  25.         serverSocket.close();
  26.     }
  27. }
复制代码
客户端:
  1. public class TcpFileClient {
  2.     public static void main(String[] args) throws Exception {
  3.         //1、获取端口与地址进行交互
  4.         Socket socket = new Socket("192.168.10.102", 9923);
  5.         //Socket socket = new Socket("127.0.0.1", 9923);
  6.         //2、获取输出流,进行输出文件
  7.         OutputStream outputStream = socket.getOutputStream();
  8.         //3、读取文件
  9.         FileInputStream fileInputStream = new FileInputStream(new File("20230702_18474242.png"));
  10.         //4、进行上传
  11.         byte[] buffer = new byte[1024];
  12.         int len;
  13.         while ((len = fileInputStream.read(buffer)) != -1){
  14.             outputStream.write(buffer, 0, len);
  15.         }
  16.         //5、进行断开连接判断
  17.         //通知服务器,已发送完毕
  18.         socket.shutdownOutput();;//已发送完
  19.         //获取输入流,获取服务端发送的数据
  20.         InputStream inputStream = socket.getInputStream();
  21.         ByteArrayOutputStream bos = new ByteArrayOutputStream();
  22.         byte[] bytes = new byte[1024];
  23.         int len2;
  24.         while ((len2 = inputStream.read(bytes)) != -1){
  25.             bos.write(bytes, 0, len2);
  26.         }
  27.         System.out.println(bos.toString());
  28.         //6、关闭资源
  29.         bos.close();
  30.         inputStream.close();
  31.         fileInputStream.close();
  32.         outputStream.close();
  33.         socket.close();
  34.     }
  35. }
复制代码
注意:tcp 网络编程时,需要先运行服务端,在运行客户端
四、UDP网络编程

案例一:UDP 通信

发送端:
  1. public class UdpSend {
  2.     public static void main(String[] args) throws Exception {
  3.         //1、创建通信链接通道
  4.         DatagramSocket datagramSocket = new DatagramSocket();
  5.         //2、创建包
  6.         String msg = "你好";
  7.         InetAddress inetAddress = InetAddress.getByName("127.0.0.1");
  8.         int post = 9923;
  9.         DatagramPacket datagramPacket = new DatagramPacket(msg.getBytes(), 0, msg.getBytes().length, inetAddress, post);
  10.         //3、发送包
  11.         datagramSocket.send(datagramPacket);
  12.         //4、关闭资源
  13.         datagramSocket.close();
  14.     }
  15. }
复制代码
接收端:
  1. public class UdpReceive {
  2.     public static void main(String[] args) throws IOException {
  3.         //1、创建通信链接通道
  4.         DatagramSocket datagramSocket = new DatagramSocket(9923);
  5.         //2、创建接收数据的包
  6.         byte[] buffer = new byte[1024];
  7.         DatagramPacket datagramPacket = new DatagramPacket(buffer, buffer.length);
  8.         //3、接收
  9.         datagramSocket.receive(datagramPacket);
  10.         System.out.println(new String(datagramPacket.getData()));//获取数据
  11.         System.out.println(datagramPacket.getPort());//获取发射器端口
  12.         System.out.println(datagramPacket.getSocketAddress());//获取包中的地址 加 发送器的端口
  13.         System.out.println(datagramPacket.getAddress());//获取包中的地址
  14.         //4、关闭资源
  15.         datagramSocket.close();
  16.     }
  17. }
复制代码
案例二:UDP 在线聊天

发送端:
  1. public class UdpSend {
  2.     public static void main(String[] args) throws Exception {
  3.         DatagramSocket socket = new DatagramSocket();
  4.         //准备数据
  5.         BufferedReader dataPacket = new BufferedReader(new InputStreamReader(System.in));
  6.         while (true){
  7.             String data = dataPacket.readLine();
  8.             byte[] dataBytes = data.getBytes();
  9.             DatagramPacket packet = new DatagramPacket(dataBytes, 0, dataBytes.length, new InetSocketAddress("192.168.10.102", 9923));
  10.             //发送数据
  11.             socket.send(packet);
  12.             if (data.equalsIgnoreCase("bye")){
  13.                 break;
  14.             }
  15.         }
  16.         //关闭资源
  17.         socket.close();
  18.     }
  19. }
复制代码
接收端:
  1. public class UdpReceive {
  2.     public static void main(String[] args) throws IOException {
  3.         DatagramSocket socket = new DatagramSocket(9923);
  4.         //接收多次
  5.        while (true){
  6.            //准备容器接收数据
  7.            byte[] container = new byte[1024];
  8.            DatagramPacket packet = new DatagramPacket(container, 0, container.length);
  9.            //阻塞接收数据
  10.            socket.receive(packet);
  11.            //断开连接
  12.            byte[] data = packet.getData();
  13.            String receiveData = new String(data);
  14.            System.out.println(receiveData);
  15.            if (receiveData.equalsIgnoreCase("bye")){
  16.                break;
  17.            }
  18.        }
  19.         //关闭资源
  20.         socket.close();
  21.     }
  22. }
复制代码
案例三:案例二改进为多线程

发送端也是接收端。通过多线程来实现。
发送端:
  1. public class TalkServiceSend implements Runnable{
  2.     private DatagramSocket socket = null;
  3.     private BufferedReader dataPacket = null;
  4.     /**
  5.      * 接收者的ip
  6.      */
  7.     private String receiveIp;
  8.     /**
  9.      * 接收者端口
  10.      */
  11.     private int receivePort;
  12.     public TalkServiceSend(String receiveIp, int receivePort) {
  13.         this.receiveIp = receiveIp;
  14.         this.receivePort = receivePort;
  15.         try {
  16.             socket = new DatagramSocket();
  17.             dataPacket = new BufferedReader(new InputStreamReader(System.in));
  18.         } catch (SocketException e) {
  19.             e.printStackTrace();
  20.         }
  21.     }
  22.     @Override
  23.     public void run() {
  24.         while (true){
  25.             try {
  26.                 String data = dataPacket.readLine();
  27.                 byte[] dataBytes = data.getBytes();
  28.                 DatagramPacket packet = new DatagramPacket(dataBytes, 0, dataBytes.length, new InetSocketAddress(this.receiveIp, this.receivePort));
  29.                 //发送数据
  30.                 socket.send(packet);
  31.                 if (data.equalsIgnoreCase("bye")){
  32.                     break;
  33.                 }
  34.             } catch (IOException e) {
  35.                 e.printStackTrace();
  36.             }
  37.         }
  38.         //关闭资源
  39.         socket.close();
  40.     }
  41. }
复制代码
接收端:
  1. public class TalkServiceReceive implements Runnable{
  2.     DatagramSocket socket = null;
  3.     /**
  4.      * 端口
  5.      */
  6.     private int port;
  7.     /**
  8.      * 发送者
  9.      */
  10.     private String sender;
  11.     public TalkServiceReceive(int port, String sender) {
  12.         this.port = port;
  13.         this.sender = sender;
  14.         try {
  15.             socket = new DatagramSocket(this.port);
  16.         } catch (SocketException e) {
  17.             e.printStackTrace();
  18.         }
  19.     }
  20.     @Override
  21.     public void run() {
  22.         //接收多次
  23.         while (true){
  24.             try {
  25.                 //准备容器接收数据
  26.                 byte[] container = new byte[1024];
  27.                 DatagramPacket packet = new DatagramPacket(container, 0, container.length);
  28.                 //阻塞接收数据
  29.                 socket.receive(packet);
  30.                 //断开连接
  31.                 byte[] data = packet.getData();
  32.                 String receiveData = new String(data);
  33.                 System.out.println(sender + " : " + receiveData);
  34.                 if (receiveData.equalsIgnoreCase("bye")){
  35.                     break;
  36.                 }
  37.             } catch (IOException e) {
  38.                 e.printStackTrace();
  39.             }
  40.         }
  41.         //关闭资源
  42.         socket.close();
  43.     }
  44. }
复制代码
测试:
  1. public class TalkStudent {
  2.     public static void main(String[] args) {
  3.         //new Thread(new TalkServiceSend("127.0.0.1", 9923)).start();
  4.         new Thread(new TalkServiceSend("10.82.148.136", 9923)).start();//虚拟机地址
  5.         new Thread(new TalkServiceReceive(9924, "老师")).start();
  6.     }
  7. }
复制代码
  1. public class TalkTeacher {
  2.     public static void main(String[] args) {
  3.         new Thread(new TalkServiceSend("192.168.10.102", 9924)).start();
  4.         new Thread(new TalkServiceReceive(9923, "学生")).start();
  5.     }
  6. }
复制代码
五、URL编程

举例:
  1. public class UrlTest {
  2.     public static void main(String[] args) throws MalformedURLException {
  3.         URL url = new URL("https://www.jd.com/?cu=true&utm_source=www.baidu.com&utm_medium=tuiguang&utm_campaign=t_1003608409_");
  4.         System.out.println(url.getProtocol()); //获取URL的协议名
  5.         System.out.println(url.getHost());        //获取URL的主机名
  6.         System.out.println(url.getPort());        //获取URL的端口号
  7.         System.out.println(url.getPath());        //获取URL的文件路径
  8.         System.out.println(url.getFile());        //获取URL的文件名
  9.         System.out.println(url.getQuery());        //获取URL的查询名
  10.     }
  11. }
复制代码
案例一:下载文件
  1. public class UrlTest {
  2.     public static void main(String[] args) throws Exception {
  3.         //1、定位到服务器上的资源位置
  4.         URL url = new URL("https://lmg.jj20.com/up/allimg/4k/s/02/2109250006343S5-0-lp.jpg");
  5.         //2、创建连接
  6.         HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
  7.         
  8.         //对于程序而言,写出去----》output/writer;读取---》input/reader
  9.         
  10.         //3、获取输入流
  11.         InputStream stream = connection.getInputStream();
  12.         //4、写入文件
  13.         FileOutputStream outputStream = new FileOutputStream("山水.jpg");
  14.         byte[] bytes = new byte[1024];
  15.         int len;
  16.         while ((len = stream.read(bytes)) != -1){
  17.             outputStream.write(bytes, 0, len);
  18.         }
  19.         //5、关闭资源
  20.         outputStream.close();
  21.         stream.close();
  22.         connection.disconnect();//断开连接
  23.     }
  24. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4