• java网络编程


    网络编程

    其本质是socket对象

    • 什么是网络:
      网络是由节点和连线构成,表示诸多对象及其相互联系。在计算机世界里,⽹络就是⼀种辅助双⽅或者多⽅能够连接在⼀起的⼯具。

    • 为什么使用网络
      就是为了联通多⽅然后进⾏通信⽤的,即把数据从⼀⽅传递给另外⼀⽅前⾯的学习编写的程序都是单机的,即不能和其他电脑上的程序进⾏通信为了让在不同的电脑上运⾏的软件,之间能够互相传递数据,就需要借助⽹络的功能。
      在这里插入图片描述

    • 协议
      网络协议为计算机网络中进行数据交换而建立的规则、标准或约定的集合。

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

    • 端口(port)
      设备与外界通讯交流的出入口。端口可分为虚拟端口和物理端口,其中虚拟端口指计算机内部或交换机路由器内的端口,不可见。例如计算机中的80端口、21端口、23端口等。物理端口又称为接口,是可见端口,计算机背板的RJ45网口,交换机路由器集线器等RJ45端口。电话使用RJ11插口也属于物理端口的范畴。

    • 常见知名端口:
      80端⼝分配给HTTP服务
      21端⼝分配给FTP服务
      443 端口分配给HTTPS服务

    • 动态端口
      动态端⼝的范围是从1024到65535,之所以称为动态端⼝,是因为它⼀般不固定分配某种服务,⽽是动态分配。
      动态分配是指当⼀个系统进程或应⽤程序进程需要⽹络通信时,它向主机申请⼀个端⼝,主机从可⽤的端⼝号中分配⼀个供它使⽤。当这个进程关闭时,同时也就释放了所占⽤的端⼝号。

    • 查看端口
      ⽤“netstat”查看端⼝状态

    IP地址

    • 什么是IP地址
      IP地址是指互联网协议地址(英语:Internet Protocol Address,又译为网际协议地址),是IP Address的缩写。IP地址是IP协议提供的一种统一的地址格式,它为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异。

    • ip地址的分类
      用来在网络中标记一台电脑的一串数字,在网络中的唯一性

    • ip地址的分类
      1、IPv4
      在这里插入图片描述
      10.0.0.0~10.255.255.255
      172.16.0.0~172.31.255.255
      192.168.0.0~192.168.255.255

    2、IPv6

    • 子网掩码
      用来指定IP地址哪些位是网络号、哪些是主机号。
      子网掩码只有⼀个作⽤,就是将某个IP地址划分成⽹络地址和主机地址两部分⼦⽹掩码的设定必须遵循⼀定的规则。
      与IP地址相同,子网掩码的⻓度也是32位
      1、左边是网络位,⽤⼆进制数字“1”表示;
      2、右边是主机位,⽤⼆进制数字“0”表示。
      假设IP地址为“192.168.1.1”子网掩码为“255.255.255.0”

    socket简介

    • 网络中进程间通信
      网络层的“ip地址”可以唯⼀标识⽹络中的主机,而传输层的“协议+端⼝”可以唯⼀标识主机中的应⽤程序(进程)。这样利⽤ip地址、协议、端口就可以标识网络的进程了,⽹络中的进程通信就可以利⽤这个标志与其它进程进⾏交互。这个就是网络编程,又称为socket编程。
    • 什么是socket
      socket(简称套接字)是进程间通信的⼀种⽅式,它与其他进程间通信的⼀个主要不同是——它能实现不同计算机间的进程间通信,我们⽹络上各种各样的服务大多都是基于Socket来完成通信的。

    创建socket
    在Java中使⽤java.net包中的类实现socket的创建:

    import java.net.DatagramSocket;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    # 创建一个基于UDP协议的Socket对象
    DatagramSocket ds =  new DatagramSocket();
    # 创建一个基于TCP协议的Socket客户端对象
    Socket socket = new Socket("127.0.0.1", 8080);
    # 创建一个基于TCP协议的Socket服务端对象
    ServerSocket ss = new ServerSocket(8080);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    创建⼀个tcp socket(TCP套接字):

    import java.net.ServerSocket;
    import java.net.Socket;
    
    # 创建一个基于TCP协议的Socket客户端对象
    Socket socket = new Socket("127.0.0.1", 8080);
    # 创建一个基于TCP协议的Socket服务端对象
    ServerSocket ss = new ServerSocket(8080);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    创建⼀个tcp socket(UDP套接字):

    import java.net.DatagramSocket;
    
    # 创建一个基于UDP协议的Socket对象
    DatagramSocket ds =  new DatagramSocket();
    
    • 1
    • 2
    • 3
    • 4

    UDP协议

    • 什么是UDP协议
      UDP(user datagram protocol)—⽤户数据报协议,是OSI(Open System Interconnection,开放式系统互联) 参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务。UDP不提供可靠性,它只是把应⽤程序传给IP层的数据报发送出去,但是并不能保证它们能到达⽬的地。由于UDP在传输数据报前不⽤在客户和服务器之间建⽴⼀个连接,且没有超时重发等机制,故而传输速度很快。
      UDP是⼀种⾯向⽆连接的协议,每个数据报都是⼀个独⽴的信息,包括完整的源地址或⽬的地址,它在⽹络上以任何可能的路径传往⽬的地,因此能否到达⽬的地,到达⽬的地的时间以及内容的正确性都是不能被保证的。

    1、无连接
    2、不可靠
    3、不安全

    追求速度的网络协议

    DatagramSocket对象是java封装的基于UDP网络协议socket(套接字)

    DatagramPacket进行数据的封装和解封装

    • udp网络程序-发送数据
      创建⼀个udp客户端程序的流程是简单,具体步骤如下:
      1、 创建客户端套接字
      2、 发送/接收数据
      3、 关闭套接字
      在这里插入图片描述
    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetSocketAddress;
    import java.net.SocketException;
    
    public class TestUDPSendData {
    
    	public static void main(String[] args) {
    		DatagramSocket ds = null;
    		try {
    			ds = new DatagramSocket(8888);
    			String str = "lbs";
    			DatagramPacket dp = new DatagramPacket(str.getBytes("gbk"), str.getBytes("gbk").length,
    					new InetSocketAddress("192.168.31.23", 8080));
    
    			ds.send(dp);
    
    		} catch (SocketException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		} finally {
    			if (ds != null)
    				ds.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

    udp⽹络程序-接受数据

    • 不绑定IP地址和端口
      接受数据存在两种情况,第一种就是我们默认不绑定IP地址和端口,有python解释器自动的为我们动态的分配:
    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetSocketAddress;
    import java.net.SocketException;
    
    public class TestUDPSendData {
    
    	public static void main(String[] args) {
    		DatagramSocket ds = null;
    		try {
    			ds = new DatagramSocket();
    			String str = "lbs";
    			DatagramPacket dp = new DatagramPacket(str.getBytes("gbk"), str.getBytes("gbk").length, 
    					new InetSocketAddress("192.168.31.23", 8080));
    			
    			ds.send(dp);
    			
    		} catch (SocketException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		} finally {
    			if (ds != null) ds.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
    • 绑定IP地址和端口
      使用bind方法来指定
    package com.openlab.day20.network;
    
    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetSocketAddress;
    import java.net.SocketException;
    
    public class TestUDPSendData {
    
    	public static void main(String[] args) {
    		DatagramSocket ds = null;
    		try {
    			ds = new DatagramSocket(new InetSocketAddress("192.168.31.23", 2233));
    			String str = "lbs";
    			DatagramPacket dp = new DatagramPacket(str.getBytes("gbk"), str.getBytes("gbk").length, 
    					new InetSocketAddress("192.168.31.23", 8080));
    			
    			ds.send(dp);
    			
    		} catch (SocketException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		} finally {
    			if (ds != null) ds.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

    案例:为飞秋发送数据

    版本号:包编号:发送者姓名:发送者机器名:命令字:消息

    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetSocketAddress;
    import java.net.SocketException;
    import java.util.Scanner;
    
    public class TestUDPSendDataToFeiqiu {
    
    	public static void main(String[] args) {
    		DatagramSocket ds = null;
    		try {
    			ds = new DatagramSocket();
    			java.util.Scanner sc = new Scanner(System.in);
    			while(true) {
    				System.out.println("请输入您要发送的数据:");
    				String str = sc.nextLine();
    				if (str.equalsIgnoreCase("exit")) {
    					break;
    				}
    				DatagramPacket dp = new DatagramPacket(str.getBytes(), str.getBytes().length, 
    						new InetSocketAddress("127.0.0.1", 2425));
    				
    				ds.send(dp);
    			}
    			
    		} catch (SocketException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		} finally {
    			if (ds != null) ds.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
    • udp网络通信过程
      在这里插入图片描述
      在这里插入图片描述
    • UDP多线程编程
      发送和接受分别有一个独立的子线程来运行。
    
    import java.io.IOException;
    import java.io.UnsupportedEncodingException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetSocketAddress;
    import java.net.SocketException;
    import java.util.Scanner;
    
    public class TestUDPReviceData {
    
    	public static void main(String[] args) {
    		new TestUDPReviceData().begin();
    	}
    	
    	public void begin() {
    		DatagramSocket ds = null;
    		try {
    			ds = new DatagramSocket(9999);
    			byte[] buf = new byte[1024];
    			
    			DatagramPacket dp = new DatagramPacket(buf, buf.length);
    			
    			new Thread(new SendInfo(ds)).start();
    			while(true) {
    				ds.receive(dp);
    				System.out.println("接受到值"+ dp.getAddress().getHostAddress() +"传递过来的值");
    				String str = new String(buf, 0, buf.length, "gbk");
    				System.out.println("---->"+ str);
    			}
    			
    		} catch (SocketException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		} finally {
    			if (ds != null) ds.close();
    		}
    	}
    	
    	class SendInfo implements Runnable {
    		
    		private DatagramSocket ds;
    		private DatagramPacket dp;
    		
    		
    		
    		public SendInfo(DatagramSocket ds) {
    			this.ds = ds;
    		}
    
    		@Override
    		public void run() {
    			java.util.Scanner sc = new Scanner(System.in);
    			while(true) {
    				String msg = sc.nextLine();
    				try {
    					this.dp = new DatagramPacket(msg.getBytes("gbk"), msg.getBytes("gbk").length, new InetSocketAddress("192.168.31.23", 8080));
    					this.ds.send(dp);
    				} catch (UnsupportedEncodingException e) {
    					e.printStackTrace();
    				} 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

    TCP协议

    TCP:传输控制协议
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    安全
    可靠
    有连接的
    点对点
    长连接

    tcp服务器

    import java.io.IOException;
    import java.io.PrintWriter;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    public class ServerTcp {
    	public static void main(String[] args) {
    		ServerSocket ss = null;
    		PrintWriter out = null;
    		try {
    			ss = new ServerSocket(8888);
    			System.out.println("等待客户端连接上来……");
    			while(true) {
    				Socket socket = ss.accept();
    				
    				System.out.println(socket.getInetAddress().getHostAddress() +"连接上来了");
    				// 注意PrintWriter第二个参数,必须为true,否则会缓冲数据,导致数据无法发送
    				out = new PrintWriter(socket.getOutputStream(), true);
    				out.println("欢迎访问本系统");
    				
    			}
    		} 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

    Tcp客户端

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.net.Socket;
    import java.net.UnknownHostException;
    
    public class Client {
    
    	public static void main(String[] args) {
    		Socket s = null;
    		BufferedReader br = null;
    		
    		try {
    			s = new Socket("192.168.31.23", 8888);
    //			s = new Socket("127.0.0.1", 8888);
    			
    			br = new BufferedReader(new 
    InputStreamReader(s.getInputStream()));
    			System.out.println(br.readLine());
    			
    		} catch (UnknownHostException e) {
    			e.printStackTrace();
    		} 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

    在这里插入图片描述

  • 相关阅读:
    Swift 单元测试
    Java NIO中的Files类的使用
    微信小程序八(自定义tabBar)
    【博客529】linux cpu的 “steal time“含义
    python货币转换
    人工智能水印技术入门:工具与技巧
    Allegro DFM Ravel Rule 丝印线段到PAD 间距检查
    MySQL之数据查询(分类汇总与排序)
    看交互设计如何集成到Scrum敏捷流程中
    使用LDA(线性判别公式)进行iris鸢尾花的分类
  • 原文地址:https://blog.csdn.net/weixin_53136274/article/details/126445395