本系列博客汇总在这里:Java系列_汇总


一、计算机网络

  计算机网络是指将地理位置不同的具有独立功能的多台计算机以及外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件以及通信的协议的管理下,实现资源共享和信息传递的计算机系统。

二、网络编程

网络编程就是用来实现网络互通的不同计算机运行程序之间进行数据的交换的编程。

三、网络模型

Java系列(53)——网络编程_自动生成
Java系列(53)——网络编程_服务端_02

四、网络通信的三要素

1、IP

① IP 的最大值 233.255.255.255。
② 可以设置的区间是 1.0.0.0——233.255.255.255。

2、IP 的查看

  1. 使用 docs 命令输入执行 ipconfig
    Java系列(53)——网络编程_自动生成_03
    Java系列(53)——网络编程_自动生成_04
  2. 查看要通信的主机 IP 是否畅通:ping [ip]
    Java系列(53)——网络编程_java_05

3、端口号

  1. 用于标识进程的逻辑地址,不同的进程端口不同。
  2. 每一台计算机上的端口都不能重复!
    Java系列(53)——网络编程_客户端_06
  3. 如何查看端口号:使用 docs 命令 netstat –ano
    Java系列(53)——网络编程_自动生成_07

4、传输的协议

  1. 协议就是计算机通信的规则。
    Java系列(53)——网络编程_java_08
  2. 常见的有两种协议:TCP 和 UDP 协议。
    UDP
    (1)将数据源和目的地封装到数据包中,不需要建立连接。
    (2)每个数据包的大小限制在 64k。
    (3)因为不建立连接,所以安全性差,速度快。 Java系列(53)——网络编程_java_09
    TCP
    (1)建立连接形成传输数据的通道,然后再传输数据,通过三次的握手。
    (2)安全性高,效率低。
    Java系列(53)——网络编程_java_10
五、Socket
  • Socket 是网络编程提供的一种机制,通信的两端都要有 socket,网络通信其实就是 socket 间的通信,数据在两个 socket 间的 io 流上通信。
    Java系列(53)——网络编程_自动生成_11
六、InetAddress 类
  1. InetAddress 是用于管理 IP 的类,没有构造器
    (1)单例模式。
    (2)根据静态的方法来返回该对象。
    Java系列(53)——网络编程_服务端_12
  2. 示例
    public class IPAddressDemo
    {
    	public static void main(String[] args)
    	{		
    		try
    		{
    			// 获得本机 IP 地址
    			InetAddress ia = InetAddress.getLocalHost();
    			
    			// 获得本机 IP 地址字符串
    			String ip = ia.getHostAddress();
    			System.out.println("本机IP:"+ip);
    			
    			// 获得主机名(计算机名)
    			String name = ia.getHostName();
    			System.out.println("主机名:"+name);
    			
    			// 根据主机名称来获得IP地址
    			InetAddress ia1 = ia.getByName(name);
    			System.out.println("主机名和IP:"+ia1);
    			
    		} catch (UnknownHostException e)
    		{
    			// TODO 自动生成的 catch 块
    			e.printStackTrace();
    		}
    	}
    }
    
    Java系列(53)——网络编程_服务端_13
七、UDP 通信

Java系列(53)——网络编程_自动生成_14

八、客户端设计

1、创建服务端嵌套字

Java系列(53)——网络编程_自动生成_15

2、创建数据包

Java系列(53)——网络编程_java_16

3、发送数据包

Java系列(53)——网络编程_自动生成_17

九、服务端设计

1、创建 socket 服务对象

  • UDP 服务端的构造器
    Java系列(53)——网络编程_java_18

2、接收数据:使用数据包的方式来接收,用到 DatagramPacket,此类表示数据包

Java系列(53)——网络编程_自动生成_19

3、数据包的接收

4、解析数据包

Java系列(53)——网络编程_服务端_20

5、释放资源

  1. 关闭套接字。
  2. 示例源码
    服务端
    public class UDPServer
    {
    	public static void main(String[] args)
    	{	
    		DatagramSocket ds = null;
    		try
    		{
    			// 创建 UDP 服务端的对象,必须指定端口
    			ds = new DatagramSocket(10002);
    			
    			// 定义接收数据的字节数组
    			byte[] bs = new byte[1024];
    			
    			// 定义接收的数据包
    			DatagramPacket dp = new DatagramPacket(bs, bs.length);
    			System.out.println("服务器已经启动!");
    			
    			// 数据包的接收
    			ds.receive(dp);
    			
    			// 获得发送端的IP
    			InetAddress ia = dp.getAddress();		
    			
    			// 获得数据包中的数据,这个数组长度是我们自己定义时的长度(1024)
    			byte[] bs1 = dp.getData();
    			
    			// 获得接收的数据长度(实际接收的数据长度)
    			int len = dp.getLength();
    		
    			// 组装接收的数据
    			String data = new String(bs,0,len);
    						
    			System.out.println(ia.getHostAddress()+"发送了:"+ data);
    
    		} catch (SocketException e)
    		{
    			// TODO 自动生成的 catch 块
    			e.printStackTrace();
    		} catch (IOException e)
    		{
    			// TODO 自动生成的 catch 块
    			e.printStackTrace();
    		}finally
    		{
    			if(ds != null)
    			{
    				ds.close();
    			}
    		}
    	}
    }
    
    客户端
    public class UDPClient
    {
    	public static void main(String[] args)
    	{
    		DatagramSocket ds = null;
    		try
    		{
    			// 创建客户端的套接字对象
    			ds = new DatagramSocket();
    			
    			// 定义一个要发送的内容
    			byte[] bs = "Hello".getBytes();
    			
    			// 创建要发送的目的地的IP对象(本机IP)
    			InetAddress ia = InetAddress.getByName("192.168.43.35");
    			
    			// 打数据包
    			DatagramPacket dp = new DatagramPacket(bs, bs.length,ia,10002);
    			
    			// 发送
    			ds.send(dp);
    			
    		} catch (SocketException e)
    		{
    			// TODO 自动生成的 catch 块
    			e.printStackTrace();
    		} catch (UnknownHostException e)
    		{
    			// TODO 自动生成的 catch 块
    			e.printStackTrace();
    		} catch (IOException e)
    		{
    			// TODO 自动生成的 catch 块
    			e.printStackTrace();
    		}finally
    		{
    			if(ds != null)
    			{
    				ds.close();
    			}
    		}
    	}
    }
    
    结果图:
    Java系列(53)——网络编程_自动生成_21
十、UDP 从控制台输入数据发送
  • 示例源码
    服务端
    public class UDPServer
    {
    	public static void main(String[] args)
    	{	
    		DatagramSocket ds = null;
    		try
    		{
    			// 创建 UDP 服务端的对象,必须指定端口
    			ds = new DatagramSocket(10007);
    			
    			// 定义接收数据的字节数组
    			byte[] bs = new byte[1024];
    			
    			// 定义接收的数据包
    			DatagramPacket dp = new DatagramPacket(bs, bs.length);
    			System.out.println("服务器已经启动!");
    						
    			while(true)
    			{				
    				// 数据包的接收
    				ds.receive(dp);
    				
    				// 获得发送端的IP
    				InetAddress ia = dp.getAddress();		
    				
    				// 获得数据包中的数据
    				byte[] bs1 = dp.getData();
    				
    				// 获得接收的数据长度(实际接收的数据长度)
    				int len = dp.getLength();
    			
    				// 组装接收的数据
    				String data = new String(bs,0,len);
    				
    				if("exit".equals(data))
    				{
    					break;
    				}
    				
    				System.out.println(ia.getHostAddress()+"发送了:"+ data);
    			}
    
    		} catch (SocketException e)
    		{
    			// TODO 自动生成的 catch 块
    			e.printStackTrace();
    		} catch (IOException e)
    		{
    			// TODO 自动生成的 catch 块
    			e.printStackTrace();
    		}finally
    		{
    			if(ds != null)
    			{
    				ds.close();
    			}
    		}
    	}
    }
    
    客户端
    public class UDPClient
    {
    	public static void main(String[] args)
    	{
    		DatagramSocket ds = null;
    		BufferedReader br = null;
    		try
    		{
    			// 创建控制台的输入流
    			br = new BufferedReader(new InputStreamReader(System.in));
    			
    			// 创建客户端的套接字对象
    			ds = new DatagramSocket();
    			
    			// 创建要发送的目的地的IP对象(本机IP)
    			InetAddress ia = InetAddress.getByName("192.168.222.1");			
    			
    			while(true)
    			{
    				// 从控制台读取一行
    				String line = br.readLine();				
    		
    				// 退出
    				if("exit".equals(line))
    				{
    					break;
    				}
    				
    				byte[] bs = line.getBytes();			
    				
    				// 打数据包
    				DatagramPacket dp = new DatagramPacket(bs, bs.length,ia,10007);
    				
    				// 发送
    				ds.send(dp);
    			}		
    			
    		} catch (SocketException e)
    		{
    			// TODO 自动生成的 catch 块
    			e.printStackTrace();
    		} catch (UnknownHostException e)
    		{
    			// TODO 自动生成的 catch 块
    			e.printStackTrace();
    		} catch (IOException e)
    		{
    			// TODO 自动生成的 catch 块
    			e.printStackTrace();
    		}finally
    		{
    			try
    			{
    				if(ds != null)
    				{
    					ds.close();
    				}
    				if(br != null)
    				{					
    					br.close();				
    				}
    			} catch (IOException e)
    			{
    				// TODO 自动生成的 catch 块
    				e.printStackTrace();
    			}
    		}
    	}
    }
    
    • 结果图:
      Java系列(53)——网络编程_服务端_22
      Java系列(53)——网络编程_客户端_23
十一、UDP 简易聊天室

Java系列(53)——网络编程_java_24
此部分代码较长,粘贴至此处不便于查看,请点击链接下载源码:示例代码

结果图:
Java系列(53)——网络编程_服务端_25
Java系列(53)——网络编程_网络编程_26
提示:也可以把聊天室作为一个类,再新建测试类(主类),新建聊天室线程,用于指定目的 IP,就可以实现多个 IP 进行信息发送了。

  • 示例代码
    package cn.tx.net3;
    
    public class CharRoom implements Runnable
    {	
    	private String ip;
    		
    	public CharRoom(String ip)
    	{
    		super();
    		this.ip = ip;
    	}
    
    	public void run()
    	{
    		// 创建接收端对象线程的实现
    		UDPClient uc = new UDPClient(ip,10003);
    		
    		UDPServer us = new UDPServer(10001);
    		
    		// 发送端的线程
    		Thread t = new Thread(uc);
    		
    		// 接收端的线程		
    		Thread t1 = new Thread(us);
    		
    		// 启动两个线程
    		t.start();
    		t1.start();		
    	}
    }
    
    package cn.tx.net3;
    
    public class Test
    {
    	public static void main(String[] args)
    	{		
    		// 创建聊天室
    		Thread t = new Thread(new CharRoom("192..."));
    		//Thread t1 = new Thread(new CharRoom("192..."));
    		//Thread t2 = new Thread(new CharRoom("192..."));
    		
    		// 启动线程
    		t.start();
    		//t1.start();
    		//t2.start();
    	}
    }
    
十二、TCP 的socket通信

Java系列(53)——网络编程_自动生成_27

1、服务端

  1. 创建服务器的Socket对象,指定端口
    Java系列(53)——网络编程_服务端_28

  2. 监听并获得客户端的对象 socket
    Java系列(53)——网络编程_网络编程_29

  3. 获得输入流
    Java系列(53)——网络编程_网络编程_30

  4. 读取数据

  5. 释放资源

2、客户端

  1. 创建客户端 socket 套接字对象
    Java系列(53)——网络编程_客户端_31
  2. 获得输出流
    Java系列(53)——网络编程_服务端_32
  3. 写数据
  4. 释放资源

3、示例代码

  1. 服务端
    public class TCPserver
    {
    	public static void main(String[] args)
    	{	
    		BufferedReader br = null;
    		ServerSocket ss = null;
    		Socket s = null;
    		try
    		{
    			// 创建服务器端的服务套接字
    			ss = new ServerSocket(10000);
    			
    			// 接收到了一个连接的请求,等待有客户端来建立连接
    			s = ss.accept();
    			
    			// 获得通道的输入流对象(字节流)			
    			InputStream in = s.getInputStream();
    			
    			br = new BufferedReader(new InputStreamReader(in));
    						
    			// 读取一行
    			String line = br.readLine();
    					
    			// 获得客户端的 ip 地址 
    			InetAddress ia = s.getInetAddress();			
    			
    			System.out.println(ia.getHostAddress() + "发送了:" +line);
    		
    		} catch (IOException e)
    		{
    			// TODO 自动生成的 catch 块
    			e.printStackTrace();
    		}finally
    		{			
    			try
    			{
    				if(br != null)
    				{
    					br.close();
    				}
    				if(s != null)
    				{
    					s.close();
    				}
    				if(ss != null)
    				{
    					ss.close();
    				}
    				
    			}catch (IOException e1)
    			{
    				// TODO 自动生成的 catch 块
    				e1.printStackTrace();
    			}
    		}
    	}
    }
    
    public class TCPClient
    {
    	public static void main(String[] args)
    	{		
    		Socket s = null;
    		BufferedWriter writer = null;				
    		try
    		{
    			// 获得本机 IP 地址(也可以指定 IP)
    			InetAddress ia = InetAddress.getLocalHost();
    			
    			// 获得本机 IP 地址字符串
    			String ip = ia.getHostAddress();
    			
    			// 创建客户端的服务套接字对象,去请求服务器的ServerSocket
    			s = new Socket(ip,10000);
    			
    			// 获得输出流对象(字节流)
    			OutputStream out = s.getOutputStream();	
    								
    		    writer = new BufferedWriter(new OutputStreamWriter(out));		 
    			writer.write("魏宇轩,你好!");
    			System.out.println("消息已发送!");
    		    			    		    			
    		} catch (Exception e)
    		{
    			// TODO 自动生成的 catch 块
    			e.printStackTrace();
    		}finally
    		{
    			try
    			{				
    				if(writer != null)
    				{
    					writer.close();
    				}
    				if(s != null)
    				{
    					s.close();
    				}
    			} catch (IOException e)
    			{
    				// TODO 自动生成的 catch 块
    				e.printStackTrace();
    			}
    		}		
    	}
    }
    
    Java系列(53)——网络编程_网络编程_33
    Java系列(53)——网络编程_客户端_34
十三、TCP 聊天程序
  • 示例源码
    public class TCPServer
    {
    	/**
    	 * 服务端的端口
    	 */
    	private int port;
    	
    	
    	
    	public TCPServer(int port)
    	{
    		super();
    		this.port = port;
    		Recevice r = new Recevice();
    		Thread t = new Thread(r);
    		t.start();
    	}
    
    	/**
    	  * 内部类
    	 */
    	class Recevice implements Runnable
    	{
    		public void run()
    		{
    			ServerSocket  ss = null;
    			Socket s = null;
    			BufferedReader br = null;
    			try
    			{
    				// 创建服务端的Socket
    				ss = new ServerSocket(port);
    				System.out.println("服务器已启动!");
    				
    				// 接收客户端Socket 
    				s = ss.accept();
    				// 获得客户端的 ip
    				InetAddress ia = s.getInetAddress();
    				
    				// 获得输入流
    				InputStream in = s.getInputStream();				
    				br = new BufferedReader(new InputStreamReader(in));
    				
    				String line = null;
    				while((line = br.readLine()) != null)
    				{
    					System.out.println(ia.getHostAddress()+"说:"+line);
    					if("exit".equals(line))
    					{
    						break;
    					}
    				}				
    				
    			} catch (IOException e)
    			{
    				// TODO 自动生成的 catch 块
    				e.printStackTrace();
    			}finally
    			{
    				try
    				{
    					if(br != null)
    					{
    						br.close();
    					}
    					if(s != null)
    					{
    						s.close();
    					}
    					if(ss != null)
    					{
    						ss.close();
    					}					
    				} catch (IOException e)
    				{
    					// TODO 自动生成的 catch 块
    					e.printStackTrace();
    				}
    			}
    		}		
    	}
    	
    	public static void main(String[] args)
    	{		
    		new TCPServer(20000);
    	}
    }
    
    public class TCPClient
    {
    	private String ip;
    	
    	private int port;
    	
    	public TCPClient(String ip, int port)
    	{
    		super();
    		this.ip = ip;
    		this.port = port;
    		
    		Sender s = new Sender();
    		
    		Thread t = new Thread(s);
    		
    		t.start();		
    	}
    	
    	class Sender implements Runnable
    	{
    		public void run()
    		{
    			Socket s = null;
    			
    			BufferedReader br = null;
    			
    			BufferedWriter bw = null;
    			try
    			{
    				s = new Socket(ip,port);
    				
    				// 从控制台输入
    				br = new BufferedReader(new InputStreamReader(System.in));
    				
    				// 获得输出通道
    				OutputStream out = s.getOutputStream();
    				
    				bw = new BufferedWriter(new OutputStreamWriter(out));
    				
    				String line = null;
    				
    				while((line = br.readLine()) != null)
    				{
    					if("exit".equals(line))
    					{
    						break;
    					}
    					System.out.println("我说:\n"+line);
    					bw.write(line);
    					bw.newLine();
    					bw.flush();
    				}	
    				
    			} catch (Exception e)
    			{
    				// TODO 自动生成的 catch 块
    				e.printStackTrace();
    			}finally
    			{
    				try
    				{
    					if(bw != null)
    					{
    						bw.close();
    					}
    					if(br != null)
    					{
    						br.close();
    					}
    					if(s != null)
    					{
    						s.close();
    					}
    				
    				} catch (IOException e)
    				{
    					// TODO 自动生成的 catch 块
    					e.printStackTrace();
    				}
    			}
    		}
    	}	
    	public static void main(String[] args)
    	{
    		new TCPClient("192.168.43.35", 10000);
    	}
    }
    
    Java系列(53)——网络编程_自动生成_35

如有错误,欢迎指正!