• 什么是网络编程?


    可以让设备中的程序与网络上的其他设备中的成勋数据交互(实现网络通讯)

    java提供了哪些网络编程的解决方案

    java.net.*包下提供了网络编程的解决方案

    基本通讯架构

    • CS架构:(Client客户端   /   Server服务端)
    • BS架构: (Browser浏览器  /  Server服务端)

    网络通讯的三要素

    ip地址:(cmd -> ipconfig:IPv4(32字节))

            设备在网络中的唯一标识(上网设备上的身份号码)

            IP地址的两种形式:IPv4(32字节)、IPv6(128位):号称可以为地球上每一粒沙子编号

            IP域名:记录了服务器的ip

            公网IP:是可以链接互联网的IP地址

            内网ip也局域网ip,只能组织机构内部使用

            192.168.开头的都是常见的局域网地址

            192.168.00--192.168.255.255专门为组织机构内部使用

            127.0.0.1 、 localhost本机IP,只会寻找当前所在主机

    •  IP常见命令:

      •  ipconfig:查看IP地址

      •  ping IP地址:看链接通不通
    • IP地址相关的类:

      • InetAddress的常用方法如下:

    1. import java.io.IOException;
    2. import java.net.InetAddress;
    3. public class InetAddressText {
    4. public static void main(String[] args) throws IOException {
    5. //获取本机的IP地址对象
    6. InetAddress ip1 = InetAddress.getLocalHost();
    7. System.out.println(ip1.getHostName());
    8. System.out.println(ip1.getHostAddress());
    9. ///获取指定的ip或则域名的IP地址对象
    10. InetAddress ip2 = InetAddress.getByName("www.baidu.com");
    11. System.out.println(ip2.getHostName());
    12. System.out.println(ip2.getHostAddress());
    13. //相当于ping
    14. System.out.println(ip2.isReachable(6000));
    15. }
    16. }

    端口:(可以标志0-65535个应用程序)(自己开发的程序用注册端口号)

    应用程序在设备中唯一的标识

    周知端口:0-1023,被预先定义的知名应用占用(http80、ftp21)
    注册端口:1024-49151,分配给用户进程或某些应用程序
    动态端口:49152-65535,之所以被称为动态端口,是因为她一般不固定分配某种进程,而是动态分配

    协议:

    链接和数据在网络中传输的规则

    开放式网络互连标准:()

    osi网络参考模型:全球网络互联网标准

    TCP/IP网络模型:事实上的国际标准

    传输层2个通讯协议

    UDP(用户数据协议),TCP传输控制协议

    UDP协议:

    • 特点:无连接,不可靠通讯
    • 不事先建立链接,数据按照包发,一包数据包含:自己的ip、程序端口、目的IP、程序端口和数据(限制在64KB内)等等。
    • 发送不管对方是否在线,数据在中间丢失也不管,如果接受方收到数据也不返回确认
    • 通讯效率高,视频,通话应用

    TCP协议:

    • 特点:面向链接,可靠通讯
    • tcp的最终目的:要保证在不可靠的信道上实现可靠传输 
    • YCP主要有三个步骤实现可靠传输:三次握手建立链接,传输数据进行确认。四次挥手断开连接
    • 三次握手:发出链接请求、返回一个响应、发出确认信息,确认链接、
    • 四次挥手:发出断开请求、返回一个响应:稍等、返回一个响应,确认断开、发出正式确认断开链接

    UDP通讯

    java提供了Java.net.DatagramSocket类来实现UDP通讯

    DatagramSocket类:用于创建客户端、服务端:

    客户端:

    1. package com.Game_All.UDP;
    2. import java.io.IOException;
    3. import java.net.*;
    4. public class Client {
    5. public static void main(String[] args) throws IOException {
    6. //1、创建客户端对象
    7. DatagramSocket socket = new DatagramSocket();
    8. //2、创建数据包对象
    9. /*public DatagramPacket(byte buf[], int length,
    10. InetAddress address, int port) {
    11. this(buf, 0, length, address, port);*/
    12. byte[] bytes = "我是快乐的客户端,我爱你黄洁".getBytes();
    13. /*
    14. 参数一:封装要发出去的数据。
    15. 参数二:发送出去的数据大小(字节个数)
    16. 参数三:服务端的TP地址(找到服务端主机)
    17. 参数四:服务端程序的端口
    18. */
    19. DatagramPacket packet = new DatagramPacket(bytes,bytes.length,InetAddress.getLocalHost(),6666);
    20. //3、发送
    21. socket.send(packet);
    22. System.out.println("客户端发送完毕");
    23. socket.close();//释放资源
    24. }
    25. }

    服务端:

    1. package com.Game_All.UDP;
    2. import java.io.IOException;
    3. import java.net.DatagramPacket;
    4. import java.net.DatagramSocket;
    5. import java.net.SocketException;
    6. public class Server {
    7. public static void main(String[] args) throws IOException {
    8. //1、创建一个服务端(注册端口)
    9. DatagramSocket socket = new DatagramSocket(6666);
    10. //2、创建一个数据包对象,用于接收数据的
    11. byte[] buffer = new byte[1024*64];//64kb
    12. DatagramPacket packet = new DatagramPacket(buffer,buffer.length);
    13. //3、接收
    14. socket.receive(packet);
    15. //4、从字节数组中,吧即受到的数据直接打印出来
    16. //接收到多少就到处多少
    17. int len = packet.getLength();
    18. String rs = new String(buffer,0,len);
    19. System.out.println(rs);
    20. System.out.println(packet.getAddress().getHostAddress());
    21. System.out.println(packet.getPort());
    22. socket.close();
    23. }
    24. }

    先运行服务端!!!!

    多发多收

    1. package com.Game_All.UDP;
    2. import java.io.IOException;
    3. import java.net.*;
    4. import java.util.Scanner;
    5. public class Client {
    6. public static void main(String[] args) throws IOException {
    7. //1、创建客户端对象
    8. DatagramSocket socket = new DatagramSocket();
    9. //2、创建数据包对象
    10. /*public DatagramPacket(byte buf[], int length,
    11. InetAddress address, int port) {
    12. this(buf, 0, length, address, port);*/
    13. /*
    14. 参数一:封装要发出去的数据。
    15. 参数二:发送出去的数据大小(字节个数)
    16. 参数三:服务端的TP地址(找到服务端主机)
    17. 参数四:服务端程序的端口
    18. */
    19. Scanner scan = new Scanner(System.in);
    20. while (true){
    21. System.out.println("请说:");
    22. String msg = scan.nextLine();
    23. if ("exit".equals(msg)){
    24. System.out.println("欢迎下次光临!退出成功");
    25. socket.close();
    26. break;
    27. }
    28. byte[] bytes = msg.getBytes();
    29. DatagramPacket packet = new DatagramPacket(bytes,bytes.length,InetAddress.getLocalHost(),6666);
    30. //3、发送
    31. socket.send(packet);
    32. }
    33. }
    34. }
    35. package com.Game_All.UDP;
    36. import java.io.IOException;
    37. import java.net.DatagramPacket;
    38. import java.net.DatagramSocket;
    39. import java.net.SocketException;
    40. public class Server {
    41. public static void main(String[] args) throws IOException {
    42. //1、创建一个服务端(注册端口)
    43. DatagramSocket socket = new DatagramSocket(6666);
    44. //2、创建一个数据包对象,用于接收数据的
    45. byte[] buffer = new byte[1024*64];//64kb
    46. DatagramPacket packet = new DatagramPacket(buffer,buffer.length);
    47. while (true) {
    48. //3、接收
    49. socket.receive(packet);
    50. //4、从字节数组中,吧即受到的数据直接打印出来
    51. //接收到多少就到处多少
    52. int len = packet.getLength();
    53. String rs = new String(buffer,0,len);
    54. System.out.println(rs);
    55. System.out.println(packet.getAddress().getHostAddress());
    56. System.out.println(packet.getPort());
    57. System.out.println("=======================");
    58. }
    59. }
    60. }

    TCP

    1. package com.Game_All.TCP;
    2. import java.io.DataOutputStream;
    3. import java.io.IOException;
    4. import java.io.OutputStream;
    5. import java.net.Socket;
    6. public class Client {
    7. public static void main(String[] args) throws IOException {
    8. //1、创建Socket对象,并同时请求与服务端程序的链接
    9. Socket socket = new Socket("127.0.0.1",8888);
    10. //2、从socket通信管道中得到一个字节输出流,用来发数据给服务端程序
    11. OutputStream os = socket.getOutputStream();
    12. //3、把低级的字节输出流包装成数据输出流
    13. DataOutputStream dos = new DataOutputStream(os);
    14. //4、开始写数据出去了
    15. dos.writeUTF("在一起,好嘛");
    16. dos.close();
    17. socket.close();
    18. }
    19. }

    1. package com.Game_All.TCP;
    2. import java.io.DataOutputStream;
    3. import java.io.IOException;
    4. import java.io.OutputStream;
    5. import java.net.Socket;
    6. public class Client {
    7. public static void main(String[] args) throws IOException {
    8. //1、创建Socket对象,并同时请求与服务端程序的链接
    9. Socket socket = new Socket("127.0.0.1",8888);
    10. //2、从socket通信管道中得到一个字节输出流,用来发数据给服务端程序
    11. OutputStream os = socket.getOutputStream();
    12. //3、把低级的字节输出流包装成数据输出流
    13. DataOutputStream dos = new DataOutputStream(os);
    14. //4、开始写数据出去了
    15. dos.writeUTF("在一起,好嘛");
    16. dos.close();
    17. socket.close();
    18. }
    19. }
    1. package com.Game_All.TCP;
    2. import java.io.DataInputStream;
    3. import java.io.DataOutputStream;
    4. import java.io.IOException;
    5. import java.io.InputStream;
    6. import java.net.ServerSocket;
    7. import java.net.Socket;
    8. public class Server {
    9. public static void main(String[] args) throws IOException {
    10. //1、创建ServerSocket的对象,同时为服务端的注册端口
    11. ServerSocket serverSocket = new ServerSocket(8888);
    12. //2、使用ServerSocket对象,调用一个accpte方法等待对象的客户链接请求
    13. Socket socket = serverSocket.accept();
    14. //3、从socke通信管道中的一个字节输入流
    15. InputStream is = socket.getInputStream();
    16. //4、把原始的字节输入流包装成数据输入流
    17. DataInputStream dis = new DataInputStream(is);
    18. //5、使用数据输入流读取客户端发送过来的消息
    19. String re = dis.readUTF();
    20. System.out.println(re);
    21. //获取客户端IP地址
    22. System.out.println(socket.getRemoteSocketAddress());
    23. dis.close();
    24. socket.close();
    25. }
    26. }

    多发多收

    1. package com.Game_All.TCP;
    2. import java.io.DataInputStream;
    3. import java.io.DataOutputStream;
    4. import java.io.IOException;
    5. import java.io.InputStream;
    6. import java.net.ServerSocket;
    7. import java.net.Socket;
    8. public class Server {
    9. public static void main(String[] args) throws IOException {
    10. //1、创建ServerSocket的对象,同时为服务端的注册端口
    11. ServerSocket serverSocket = new ServerSocket(8888);
    12. //2、使用ServerSocket对象,调用一个accpte方法等待对象的客户链接请求
    13. Socket socket = serverSocket.accept();
    14. //3、从socke通信管道中的一个字节输入流
    15. InputStream is = socket.getInputStream();
    16. //4、把原始的字节输入流包装成数据输入流
    17. DataInputStream dis = new DataInputStream(is);
    18. while (true){
    19. try {
    20. //5、使用数据输入流读取客户端发送过来的消息
    21. String re = dis.readUTF();
    22. System.out.println(re);
    23. //获取客户端IP地址
    24. System.out.println(socket.getRemoteSocketAddress());
    25. System.out.println("---------------------");
    26. } catch (IOException e) {
    27. System.out.println(socket.getRemoteSocketAddress()+"离线了");
    28. dis.close();
    29. socket.close();
    30. break;
    31. }
    32. }
    33. }
    34. }
    35. package com.Game_All.TCP;
    36. import java.io.DataOutputStream;
    37. import java.io.IOException;
    38. import java.io.OutputStream;
    39. import java.net.Socket;
    40. import java.util.Scanner;
    41. public class Client {
    42. public static void main(String[] args) throws IOException {
    43. //1、创建Socket对象,并同时请求与服务端程序的链接
    44. Socket socket = new Socket("127.0.0.1",8888);
    45. //2、从socket通信管道中得到一个字节输出流,用来发数据给服务端程序
    46. OutputStream os = socket.getOutputStream();
    47. //3、把低级的字节输出流包装成数据输出流
    48. DataOutputStream dos = new DataOutputStream(os);
    49. Scanner scanner = new Scanner(System.in);
    50. //4、开始写数据出去了
    51. while (true){
    52. System.out.println("请说:");
    53. String msg = scanner.nextLine();
    54. if ("exit".equals(msg)){
    55. dos.close();
    56. socket.close();
    57. break;
    58. }
    59. dos.writeUTF(msg);
    60. dos.flush();
    61. }
    62. }
    63. }

    不支持多个客户一个服务器

    TCP通信-多线程

    服务端

    1. package com.Game_All.TCP;
    2. import java.io.DataInputStream;
    3. import java.io.DataOutputStream;
    4. import java.io.IOException;
    5. import java.io.InputStream;
    6. import java.net.ServerSocket;
    7. import java.net.Socket;
    8. public class Server {
    9. public static void main(String[] args) throws IOException {
    10. //1、创建ServerSocket的对象,同时为服务端的注册端口
    11. ServerSocket serverSocket = new ServerSocket(8888);
    12. while (true) {
    13. try {
    14. //2、使用ServerSocket对象,调用一个accpte方法等待对象的客户链接请求
    15. Socket socket = serverSocket.accept();
    16. System.out.println("有人上线了"+socket.getRemoteSocketAddress());
    17. //3、把这个客户端对应的socket通信管道,交给一个独立的线程负责处理
    18. new ServiceReaderThread(socket).start();
    19. } catch (IOException e) {
    20. throw new RuntimeException(e);
    21. }
    22. }
    23. }
    24. }
    25. package com.Game_All.TCP;
    26. import java.io.DataInputStream;
    27. import java.io.IOException;
    28. import java.io.InputStream;
    29. import java.net.Socket;
    30. public class ServiceReaderThread extends Thread{
    31. private Socket socket;
    32. public ServiceReaderThread(Socket socket) {
    33. this.socket = socket;
    34. }
    35. @Override
    36. public void run() {
    37. InputStream is = null;
    38. try {
    39. is = socket.getInputStream();
    40. DataInputStream dis = new DataInputStream(is);
    41. while (true){
    42. try {
    43. String msg = dis.readUTF();
    44. System.out.println(msg);
    45. } catch (IOException e) {
    46. System.out.println("有人下线了"+socket.getRemoteSocketAddress());
    47. dis.close();
    48. socket.close();
    49. break;
    50. }
    51. }
    52. } catch (IOException e) {
    53. throw new RuntimeException(e);
    54. }
    55. }
    56. }

    客户端两个:

    1. package com.Game_All.TCP;
    2. import java.io.DataOutputStream;
    3. import java.io.IOException;
    4. import java.io.OutputStream;
    5. import java.net.Socket;
    6. import java.util.Scanner;
    7. public class Client {
    8. public static void main(String[] args) throws IOException {
    9. //1、创建Socket对象,并同时请求与服务端程序的链接
    10. Socket socket = new Socket("127.0.0.1",8888);
    11. //2、从socket通信管道中得到一个字节输出流,用来发数据给服务端程序
    12. OutputStream os = socket.getOutputStream();
    13. //3、把低级的字节输出流包装成数据输出流
    14. DataOutputStream dos = new DataOutputStream(os);
    15. Scanner scanner = new Scanner(System.in);
    16. //4、开始写数据出去了
    17. while (true){
    18. System.out.println("请说:");
    19. String msg = scanner.nextLine();
    20. if ("exit".equals(msg)){
    21. dos.close();
    22. socket.close();
    23. break;
    24. }
    25. dos.writeUTF(msg);
    26. dos.flush();
    27. }
    28. }
    29. }
    30. package com.Game_All.TCP;
    31. import java.io.DataOutputStream;
    32. import java.io.IOException;
    33. import java.io.OutputStream;
    34. import java.net.Socket;
    35. import java.util.Scanner;
    36. public class Client1 {
    37. public static void main(String[] args) throws IOException {
    38. //1、创建Socket对象,并同时请求与服务端程序的链接
    39. Socket socket = new Socket("127.0.0.1",8888);
    40. //2、从socket通信管道中得到一个字节输出流,用来发数据给服务端程序
    41. OutputStream os = socket.getOutputStream();
    42. //3、把低级的字节输出流包装成数据输出流
    43. DataOutputStream dos = new DataOutputStream(os);
    44. Scanner scanner = new Scanner(System.in);
    45. //4、开始写数据出去了
    46. while (true){
    47. System.out.println("请说:");
    48. String msg = scanner.nextLine();
    49. if ("exit".equals(msg)){
    50. dos.close();
    51. socket.close();
    52. break;
    53. }
    54. dos.writeUTF(msg);
    55. dos.flush();
    56. }
    57. }
    58. }

    TCP-端口转发

    客户端

    1. package com.Game_All.TCP;
    2. import java.io.DataOutputStream;
    3. import java.io.IOException;
    4. import java.io.OutputStream;
    5. import java.net.Socket;
    6. import java.util.Scanner;
    7. public class Client {
    8. public static void main(String[] args) throws IOException {
    9. //1、创建Socket对象,并同时请求与服务端程序的链接
    10. Socket socket = new Socket("127.0.0.1",8888);
    11. //创建一个独立的线程,随机负责从socket中获取服务端发送过拉力的信息
    12. new ClientReaderThread(socket).start();
    13. //2、从socket通信管道中得到一个字节输出流,用来发数据给服务端程序
    14. OutputStream os = socket.getOutputStream();
    15. //3、把低级的字节输出流包装成数据输出流
    16. DataOutputStream dos = new DataOutputStream(os);
    17. Scanner scanner = new Scanner(System.in);
    18. //4、开始写数据出去了
    19. while (true){
    20. System.out.println("请说:");
    21. String msg = scanner.nextLine();
    22. if ("exit".equals(msg)){
    23. dos.close();
    24. socket.close();
    25. break;
    26. }
    27. dos.writeUTF(msg);
    28. dos.flush();
    29. }
    30. }
    31. }
    1. package com.Game_All.TCP;
    2. import java.io.DataInputStream;
    3. import java.io.IOException;
    4. import java.io.InputStream;
    5. import java.net.Socket;
    6. public class ClientReaderThread extends Thread{
    7. private Socket socket;
    8. public ClientReaderThread(Socket socket) {
    9. this.socket = socket;
    10. }
    11. @Override
    12. public void run() {
    13. try {
    14. InputStream is = socket.getInputStream();
    15. DataInputStream dis = new DataInputStream(is);
    16. while (true){
    17. try {
    18. String msg = dis.readUTF();
    19. System.out.println(msg);
    20. } catch (IOException e) {
    21. System.out.println("有人下线了"+socket.getRemoteSocketAddress());
    22. Server.onLineSocket.remove(socket);
    23. dis.close();
    24. socket.close();
    25. break;
    26. }
    27. }
    28. } catch (IOException e) {
    29. e.printStackTrace();
    30. }
    31. }
    32. }

    服务端

    1. package com.Game_All.TCP;
    2. import java.io.DataInputStream;
    3. import java.io.DataOutputStream;
    4. import java.io.IOException;
    5. import java.io.InputStream;
    6. import java.net.ServerSocket;
    7. import java.net.Socket;
    8. import java.util.ArrayList;
    9. import java.util.List;
    10. public class Server {
    11. public static List onLineSocket = new ArrayList<>();
    12. public static void main(String[] args) throws IOException {
    13. //1、创建ServerSocket的对象,同时为服务端的注册端口
    14. ServerSocket serverSocket = new ServerSocket(8888);
    15. while (true) {
    16. try {
    17. //2、使用ServerSocket对象,调用一个accpte方法等待对象的客户链接请求
    18. Socket socket = serverSocket.accept();
    19. System.out.println("有人上线了"+socket.getRemoteSocketAddress());
    20. onLineSocket.add(socket);
    21. //3、把这个客户端对应的socket通信管道,交给一个独立的线程负责处理
    22. new ServiceReaderThread(socket).start();
    23. } catch (IOException e) {
    24. throw new RuntimeException(e);
    25. }
    26. }
    27. }
    28. }
    1. package com.Game_All.TCP;
    2. import java.io.*;
    3. import java.net.Socket;
    4. import java.util.ArrayList;
    5. import java.util.List;
    6. public class ServiceReaderThread extends Thread{
    7. private Socket socket;
    8. public ServiceReaderThread(Socket socket) {
    9. this.socket = socket;
    10. }
    11. @Override
    12. public void run() {
    13. InputStream is = null;
    14. try {
    15. is = socket.getInputStream();
    16. DataInputStream dis = new DataInputStream(is);
    17. while (true){
    18. try {
    19. String msg = dis.readUTF();
    20. System.out.println(msg);
    21. //把这个信息分发给所有客户端接收
    22. sendMsgToAll(msg);
    23. } catch (IOException e) {
    24. System.out.println("有人下线了"+socket.getRemoteSocketAddress());
    25. Server.onLineSocket.remove(socket);
    26. dis.close();
    27. socket.close();
    28. break;
    29. }
    30. }
    31. } catch (IOException e) {
    32. throw new RuntimeException(e);
    33. }
    34. }
    35. private void sendMsgToAll(String msg) throws IOException {
    36. //发送给全部在线的socket管道接收
    37. for (Socket onlineSocket : Server.onLineSocket) {
    38. OutputStream os = onlineSocket.getOutputStream();
    39. DataOutputStream dos = new DataOutputStream(os);
    40. dos.writeUTF(msg);
    41. dos.flush();
    42. }
    43. }
    44. }

    BS架构原理

    1. package com.Game_All.TCP;
    2. import java.io.DataInputStream;
    3. import java.io.DataOutputStream;
    4. import java.io.IOException;
    5. import java.io.InputStream;
    6. import java.net.ServerSocket;
    7. import java.net.Socket;
    8. import java.util.ArrayList;
    9. import java.util.List;
    10. import java.util.concurrent.ArrayBlockingQueue;
    11. import java.util.concurrent.Executors;
    12. import java.util.concurrent.ThreadPoolExecutor;
    13. import java.util.concurrent.TimeUnit;
    14. public class Server {
    15. public static void main(String[] args) throws IOException {
    16. //1、创建ServerSocket的对象,同时为服务端的注册端口
    17. ServerSocket serverSocket = new ServerSocket(8888);
    18. //创建一个县城其,负责处理铜鼓县你管道任务
    19. ThreadPoolExecutor pool = new ThreadPoolExecutor(16*2,16*2,0, TimeUnit.SECONDS,
    20. new ArrayBlockingQueue<>(8), Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());
    21. while (true) {
    22. //2、使用ServerSocket对象,调用一个accpte方法等待对象的客户链接请求
    23. Socket socket = serverSocket.accept();
    24. //3、把这个客户端对应的socket通信管道,交给一个独立的线程负责处理
    25. pool.execute(new ServiceReaderRunnable(socket));
    26. }
    27. }
    28. }
    1. package com.Game_All.TCP;
    2. import java.io.*;
    3. import java.net.Socket;
    4. public class ServiceReaderRunnable implements Runnable {
    5. private Socket socket;
    6. public ServiceReaderRunnable(Socket socket) {
    7. this.socket = socket;
    8. }
    9. @Override
    10. public void run() {
    11. try {
    12. OutputStream os = socket.getOutputStream();
    13. PrintWriter out = new PrintWriter(os, true);
    14. out.println("HTTP/1.1 200 OK");
    15. out.println("Content-Type: text/html; charset=UTF-8");
    16. out.println();
    17. out.println("
      Hello, World!
      "
      );
    18. out.close();
    19. } catch (IOException e) {
    20. e.printStackTrace();
    21. } finally {
    22. try {
    23. socket.close();
    24. } catch (IOException e) {
    25. e.printStackTrace();
    26. }
    27. }
    28. }
    29. }

  • 相关阅读:
    [已解决]react打包部署
    Java应用的混淆、加密以及加壳
    自动化测试---即selenium
    JAVA整理学习实例(四)数据结构
    C#知识|通过ADO.NET实现应用程序对数据库的增、删、改操作。
    代码随想录第43天|416. 分割等和子集,1049. 最后一块石头的重量 II, ​494.目标和,​ 474.一和零(一窍不通)
    [数组中等题] LeetCode 969. 煎饼排序
    按键检测|中断检测
    torch.nn.Conv3d()
    神经平面分布图怎么看,面部神经网络 分布图
  • 原文地址:https://blog.csdn.net/weixin_71942139/article/details/138106723