• Socket网络编程


    本文主要介绍了网络编程的相关知识,首先介绍了互联网的相关概念和常见的体系架构,之后介绍了两种网络编程(TCP与UDP),并给出了代码实现!

    一、名词概念

    • 互联网(Internet): 点与点相连
    • 万维网(www-world wide web): 端与端相连
    • 物联网(IoT-Internet of things): 物与物相连
    • 网络编程: 让计算机与计算机之间建立连接,进行通讯

    二、网络架构

    1.分层结构

    在这里插入图片描述


    2.OSI网络架构

    • 简介: Open System Interconnect (开放式系统互连)
    • 特点: 存在于概念和理论上的一种模型,它的缺点是分层太多,增加了网络工作的复杂性,所以没有大规模应用
      在这里插入图片描述
    • 第一层: :物理层为设备之间的数据通信提供传输信号和物理介质。(双绞线、 光导纤维)
      作用: 建立、维护、断开物理连接。
    • 第二层: 链路层在物理层上,通过规程或协议(差错控制)来控制传输数据的正确性。(MAC)
      作用: 接收来自物理层的位流形式的数据,并封装成帧,传送到上一层;同样,也将来自上层的数据帧,
      拆装为位流形式的数据转发到物理层;并且,还负责处理接收端发回的确认帧的信息,以便提供可靠的数据传
      输。
    • 第三层: 网络层负责定义了能够标识所有网络节点的逻辑地址。(IP地址)
      作用: 逻辑寻址,IP地址,在下两层的基础上向资源子网提供服务
    • 第四层: 传输层负责是否选择差错恢复协议、数据流重用、错误顺序重排。(TCP、 UDP)
      作用: 提供可靠和不可靠的传输机制,TCP、UDP
    • 第五层: 会话层负责使应用建立和维持会话,使通信在失效时继续恢复通信。(断点续传).
      作用: 建立、终止、管理实体间的会话连接
    • 第六层: 表示层负责定义转换数据格式及加密,允许选择以二进制或ASCII格式传输。
      作用: 封装数据的格式(加密解密、压缩解压缩)
    • 第七层: 应用层负责文件访问和管理、可靠运输服务、远程操作服务。(HTTP、 FTP、SMTP)
      作用: 人与机器电脑交互的窗口

    3.TCP/IP网络架构

    在这里插入图片描述

    • TCP协议: TCP协议: Transmission Control Protocol(传输控制协议)
      解释: 是一种面向连接的、可靠的、基于字节流的传输层通信协议。数据大小无限制。建立连接的过程需要三次握手,断开连接的过程需要四次挥手。
    • UDP协议: User Datagram Protocol用户数据报协议
      解释: 是一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务,每个包的大小64KB。

    IP协议: Internet Protocol Address(互联网协议地址/网际协议地址)

    • 解释: 分配给互联网设备的数字标签(唯标识)。—— 计算机在互联网中的地址
    • 分类:

    IPv4
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    IPV6
    在这里插入图片描述

    IP对应类:InetAddress: 代码示例

    public static void main(String[] args) throws IOException {
    		//获取本机地址
    		InetAddress inetAddress=InetAddress.getLocalHost();
    		System.out.println(inetAddress);
    		//通过主机名获取地址
    		InetAddress idAddress=InetAddress.getByName("DESKTOP-1028");
    		System.out.println(idAddress);
    		//通过主机名获取所有相关的地址对象
    		InetAddress[] inetAddresses = InetAddress.getAllByName("www.baidu.com");
    		for (InetAddress inetAddress2 : inetAddresses) {
    			System.out.println(inetAddress2);
    		}
    		//通过地址对象获取主机地址和主机名称
    		String hostAddress = inetAddress.getHostAddress();
    		String hostName = inetAddress.getHostName();
    		System.out.println(hostAddress);
    		System.out.println(hostName);
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    二、网络编程

    1.Port端口

    • 端口号: 在通信实体上进行网络通讯的 程序 的唯一标识。
    • 端口分类:
      公认端口: 0~1023
      注册端口: 1024~49151
      动态或私有端口: 49152~65535
    • 常用端口:
      MySql: 3306
      Oracle: 1521
      Tomcat: 8080
      SMTP: 25
      Web服务器: 80
      FTP服务器: 21

    2.Socket编程

    • Socket: 套接字,网络中的一个节点
    • 通讯要求: IP地址+端口号

    1.TCP编程

    • 简介: 是一种面向连接的、可靠的、基于字节流的传输层通信协议。数据大小无限制。建立连接的过程需要三次握手,断开连接的过程需要四次挥手。
    • 注意: 分为客户端Scoket与服务器ServerSocket

    开发步骤:

    • 通过Socket获取到流,服务器才可以和客户端进行数据交互
    • 服务端:ServerSocket
      1,创建ServerSocket,指定端口
      2,调用accept等待客户端接入(获取到客户端Socket映射)
      3,使用Socket输入流或输出流,与客户端进行数据交互
      4,关闭释放资源
    • 客户端:Socket
      1,创建Socket对象,指定服务器IP+端口(获取到服务器Socket映射)
      2,使用Socket获取到输出流,发起请求,给服务器发生数据(可选)
      3,使用Socket获取到输入流,接收服务器返回的数据(可选)
      4,关闭释放资源

    TCP编程示例01:无间断双向聊天

    Task.java线程任务

    import java.io.BufferedInputStream;
    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.io.OutputStreamWriter;
    import java.net.Socket;
    import java.util.Scanner;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    public class Task {	
    	private Socket socket;	
    	public Task() {
    		super();
    	}
    	public Task(Socket socket) {
    		super();
    		this.socket = socket;
    	}
    	//服务器功能线程
    	public void Message() {
    		//创建线程池(保证接收同步)
    		ExecutorService pool = Executors.newFixedThreadPool(2);		
    		//接收消息线程
    		pool.submit(new Runnable() {
    			@Override
    			public void run() {
    				try {
    					//输入流
    					InputStream is = socket.getInputStream();
    					InputStreamReader isr=new InputStreamReader(is);
    					BufferedReader br=new BufferedReader(isr);
    					while(true) {
    						String str = br.readLine();
    						System.out.println(str);
    						//判断是否关闭程序
    						if (str.equals("886")) {
    							break;
    						}
    					}
    					//关流
    					is.close();
    					socket.close();
    					isr.close();
    					br.close();
    				} catch (IOException e) {
    					e.printStackTrace();
    				}			
    			}
    		});		
    		//发送消息线程
    		pool.submit(new Runnable() {		
    			@Override
    			public void run() {
    				// TODO Auto-generated method stub
    				try {
    					OutputStream os = socket.getOutputStream();
    					OutputStreamWriter osw=new OutputStreamWriter(os);
    					BufferedWriter bw=new BufferedWriter(osw);					
    					Scanner scanner=new Scanner(System.in);		
    					//循环
    					while(true) {
    						String str=scanner.next();
    						bw.write(str);
    						bw.newLine();
    						bw.flush();
    						//跳出循环
    						if (str.equals("886")) {
    							break;
    						}
    					}
    					//关流
    					os.close();
    					socket.close();
    					osw.close();
    					bw.close();
    				} catch (IOException e) {
    					e.printStackTrace();
    				}				
    			}
    		});		
    	}	
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85

    Server.java服务器端

    import java.io.IOException;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    public class Server {
    	public static void main(String[] args) throws IOException {
    		ServerSocket serverSocket=new ServerSocket(8899);
    		//获取到客户端映射
    		Socket socket=serverSocket.accept();
    		Task task=new Task(socket);
    		task.Message();
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    Client.java服务器端

    import java.io.IOException;
    import java.net.Socket;
    import java.net.UnknownHostException;
    
    public class Client {
    
    public static void main(String[] args) throws UnknownHostException, IOException{
    		// TODO Auto-generated method stub
    		Socket socket=new Socket("10.35.162.54", 9900);
    		Task task=new Task(socket);
    		task.Message();
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    **TCP编程示例02:文件上传 **

    Client.java服务器端

    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.Socket;
    import java.net.UnknownHostException;
    public class Client {
    	public static void main(String[] args) throws UnknownHostException, IOException {
    		Socket socket=new Socket("127.0.0.1", 8989);
    		System.out.println(socket.getInetAddress());
    		//获取输入流与输出流(与服务器交互)
    		InputStream is=socket.getInputStream();
    		OutputStream os=socket.getOutputStream();
    		//创建文件输入流(读取本地文件)
    		FileInputStream fis=new FileInputStream("E:\\dog.jpeg");
    		byte[] bytes=new byte[1024];
    		int len=0;
    		while((len=fis.read(bytes))!=-1) {
    			os.write(bytes, 0, len);
    			os.flush();
    		}
    		//获取服务器返回信息
    		len=is.read(bytes);
    		String str=new String(bytes, 0, len);
    		System.out.println(str);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    注意:程序中服务器端文件流读取判断
    Server.java服务器端

    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    public class Server {
    	public static void main(String[] args) throws IOException {
    		// TODO Auto-generated method stub
    		ServerSocket serverSocket = new ServerSocket(8989);
    		Socket socket = serverSocket.accept();
    		//获取输入流与输出流(用于和客户端交互)
    		InputStream is = socket.getInputStream();
    		OutputStream os = socket.getOutputStream();		
    		//创建文件输出流(将上传的照片保存到本地)
    		FileOutputStream fos = new FileOutputStream("E:\\smile.jpg");	
    		byte[] bytes=new byte[1024]; 
    		int len=0;	
    		while((len=is.read(bytes))!=-1) {
    			fos.write(bytes, 0, len);
    			fos.flush();
    			//只有文件才有EOF默认结束标志,
    			//并且EOF默认值为-1,所以可以判断是否为结束标志
    			//所以,当读取的数据没在文件中存储时,
    			//不会读取到-1值,其len表示的是读取长度,恒大于0不能作为循条件
    			if (len<1024) {	//最后一段数据
    				break;
    			}
    		}		
    		//反馈给客户端信息
    		os.write("你好客户端,我已经收到您上传的照片".getBytes());		
    		//关流
    		fos.close();
    		is.close();
    		os.close();		
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    2.UDP编程

    • 简介: UDP协议是一种不可靠的网络协议,提供面向事务的简单不可靠信息传送服务,每个包的大小64KB,速率快
      注意: 分为接收端与发送端

    开发步骤:

    • 发送端:
      1.创建发送端的Socket对象(DatagramSocket)
      2.创建数据,并打包
      3.调用DatagramSocket对象的方法发送数据
      4.关闭发送端
    • 接收端:
      1、创建接收端的Socket对象(DatagramSocket)
      2、创建一个数据包,用于接收数据
      3、调用DatagramSocket对象的方法接收数据
      4、解析数据包,并在控制台显示
      5、关闭接收端

    文件传输

    1.接收端:

    import java.io.IOException;
        import java.net.DatagramPacket;
        import java.net.DatagramSocket;
        public class UdpGet {
            public static void main(String[] args) throws IOException {
                //1,创建接收端Socket
                DatagramSocket socket = new DatagramSocket(9999);
                //2,创建接收数据的包
                byte[] b = new byte[1024];
                DatagramPacket packet = new DatagramPacket(b, b.length);
                //3,等待接收数据
                socket.receive(packet);
                //4,获取数据
                byte[] data = packet.getData();
                //5,获取数据长度
                int length = packet.getLength();
                //6,打印输出
                System.out.println("接收的内容:"+new String(data,0,length));
                //7,关闭资源
                socket.close();
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    2.发送端:

    import java.io.IOException;
        import java.net.DatagramPacket;
        import java.net.DatagramSocket;
        import java.net.InetAddress;
        public class UdpSend {
            public static void main(String[] args) throws IOException {
                //1,创建发送端Socket对象
                DatagramSocket socket = new DatagramSocket();
                //2,准备发送内容
                byte[] sendData = "要发送的内容".getBytes();
                //3,接收端地址
                InetAddress address = InetAddress.getByName(接收端的IP);
                //4,封装发送信息包
                DatagramPacket packet = new DatagramPacket(sendData,sendData.length, address, 9999);
                //5,发送信息
                socket.send(packet);
                //6,关闭发送端
                socket.close();
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
  • 相关阅读:
    肖sir ——自动化讲解
    Firefox 开发团队对 Vue 3 进行优化效果显著
    redis五种数据类型
    第五章 数组和广义表
    Navigation 组件(一) Fragment 跳转
    「尚硅谷与腾讯云官方合作」硅谷课堂项目视频发布
    使用 Telegraf 进行综合监控
    Apache Doris 行列转换可以这样玩
    注意!11月PMP考试时间已定!
    SBT安装与配置
  • 原文地址:https://blog.csdn.net/weixin_43715360/article/details/125768784