十七、网络编程

网络编程

IP地址介绍

在这里插入图片描述

IP地址(internet Protocol)

​ 唯一标示网络上的每一台计算机

IP地址的组成

​ 32位,由4个8位二进制数组成

IP地址 = 网络地址 + 主机地址

​ 网络地址:标示计算机或网络设备所在的网段

​ 主机地址:标示特定主机或网络设备

局域网、城域网、广域网

IP地址的配置和检测

查看IP地址,检测网络是否畅通

​ 查看本机IP地址:ipconfig

​ 测试网络是否通畅:ping 目标IP地址

DNS域名解析

DNS:Domain Name System

网络服务器

通常指在网络环境下,具有较高计算能力,能够提供用户服务功能的计算机。

网络服务器

  • 邮件服务器
  • Web服务器

Microsoft IIS 服务器

APACHE Apache Tomcat 服务器 免费开源 遵循Http(超文本传输协议)

B/S:浏览器和服务器的程序 C/S:客户端和服务器的程序

网络通信协议

在这里插入图片描述
为了在网络中不同的计算机之间进行通信而建立的规则、标准或约定的集合(传输以帧为单位)

TCP面向连接传输 UDP面向无连接传输

Socket简介

socket :孔,插座

  • 每一个Socket都提供不同的服务
  • mySql服务3306端口
  • SQL Server
  • Oracle服务1512端口
  • 服务和端口绑定
  • 1-1023端口被系统占用

通信链路的断点就被称为“套接字”(英文名Socket)

是提供给应用程序的接口

Socket分类

流式套接字(SOCK_STREAM)

​ 面向连接、可靠地数据传输服务-》TCP协议

数据报式套接字(SOCK_DGRAM)-》UDP协议

​ 无连接服务

原始式套接字(SOCK_RAW) 一般不涉及

API在java.net包下

  • Socket
  • SeverSocket
  • DatagramPacket
  • DatagramSocket
  • InetAddress

基于TCP协议的Socket编程

基于TCP协议的Socket网络通信

​ 用来实现双向安全连接网络通信

Socket通信模型

​ 进行网络通信时,Socket需要借助数据流来完成数据的传递工作

服务器端:

public class LoginSever {
	public static void main(String[] args) {
		try {
			// 创建一个服务器Socket
			ServerSocket serverSocket = new ServerSocket(5000);
			// 使用accept()侦听并接受到此ServerSocket的连接
			Socket socket = serverSocket.accept();
			// 获得输入流,获得用户的请求
			InputStream is = socket.getInputStream();
			// 字符缓存流
			BufferedReader br = new BufferedReader(new InputStreamReader(is));
			// 创建缓存存储读取信息
			byte[] buffer = new byte[1024];
			// 声明变量存储信息
			String info;
			// 输出接受的信息
			while ((info = br.readLine()) != null) {
				System.out.println("客户端说:"+info);
			}
			// 发送回应
			// 发送的信息
			String output = "欢迎登陆!";
			// 创建输出字符流
			OutputStream os = socket.getOutputStream();
			// 写入
			os.write(output.getBytes());
			// 关闭流
			os.close();
			br.close();
			is.close();
			// 关闭监听
			socket.close();
			// 关闭端口
			serverSocket.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

客户端:

public class LoginClient {
	public static void main(String[] args) {
		try {
			// 创建一个客户端的Socket
			Socket socket = new Socket("localhost",5000);
			// 声明一个字符串用于发送数据
			String info = "用户名:1234;密码:1234;";
			// 建立一个输出流发送请求
			OutputStream os = socket.getOutputStream();
			os.write(info.getBytes());
			// 暂时关闭输出流
			socket.shutdownOutput();
			// 接受客户端响应
			InputStream is = socket.getInputStream();
			BufferedReader bf = new BufferedReader(new InputStreamReader(is));
			// 创建缓存接受响应
			byte[] buffer = new byte[1024];
			String reply;
			while ((reply = bf.readLine()) != null) {
				System.out.println("接收到服务器响应:"+reply);
			}
			// 释放资源
			bf.close();
			is.close();
			os.close();
			socket.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

网络编程传输的是对象

多线程处理多请求

服务器:

一直监听客户请求

一旦监听到有客户请求,立刻创建一个线程,开启线程

线程:

接收客户请求,给与客户一个响应

线程构造方法中去绑定客户端的Socket

客户端:

发送请求到服务器

接收服务器的响应

如何获得客户端IP?

InetAddress

示例:

/**
 * 用户类
 * @author 周太阳
 * @version 1.0
 * 2019年4月30日 下午2:47:17
 */
public class User {
	/**姓名*/
	private String name;
	/**密码*/
	private String password;
	public User() {
		super();
	}
	public User(String name, String password) {
		super();
		this.name = name;
		this.password = password;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
}

/**
 * 服务器多线程处理方式
 * @author 周太阳
 * @version 1.0
 * 2019年4月30日 下午2:47:52
 */
public class LoginThread extends Thread{
	private Socket socket;

	public LoginThread() {
		super();
	}

	public LoginThread(Socket socket) {
		super();
		this.socket = socket;
	}
	
	public void run() {
		
		try (
			// 获得输入流,获得用户的请求
			InputStream is = socket.getInputStream();
			// 字符缓存流
			BufferedReader br = new BufferedReader(new InputStreamReader(is));
			// 创建输出字符流
			OutputStream os = socket.getOutputStream();
			){
			// 创建缓存存储读取信息
			byte[] buffer = new byte[1024];
			// 声明变量存储信息
			String info;
			// 输出接受的信息
			while ((info = br.readLine()) != null) {
				System.out.println("客户端说:"+info);
			}
			// 获得对应主机的IP地址
			InetAddress ia = socket.getInetAddress();
			// 将IP地址转换为字符串
			String hostAddress = ia.getHostAddress();
			System.out.println("用户的IP地址是:"+hostAddress);
			// 发送信息回应
			String output = "欢迎登陆!";
			// 写入
			os.write(output.getBytes());
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	}
}

基于UDP协议的Socket编程

TCP UDP
是否连接 面向连接 面向非连接
传输可靠性 可靠 不可靠
速度

基于UDP协议的Socket网络编程步骤:

  • 利用DatagramPacket对象封装数据包
  • 利用DatagramSocket发送数据包
  • 利用DatagramSocket接收数据包
  • 利用DatagramPacket处理数据包

位于java.net包

new String();里面有很多构造,可以看下。

socket.send(DatagramPacket p) : void // 发送包

socket.receive(DatagramPacket p) : void // 接收包

案列:

/**
 * UDP客户端
 * @author 周太阳
 * @version 1.0
 * 2019年4月30日 下午2:43:27
 */
public class LoginClient {
	public static void main(String[] args) {
		// 买巧克力
		String info = "心形巧克力";
		byte[] bs = info.getBytes();
		// 对方地址或邮编
		try (
			// 快递点
			DatagramSocket socket = new DatagramSocket();
			){
			// 对方地址和邮编(端口号)
			InetAddress ia = InetAddress.getByName("localhost");
			// 包装礼物
			DatagramPacket dp = new DatagramPacket(bs, bs.length,ia,5000);	
			socket.send(dp);
			
			// 接收服务器信息
			// 创建一个字节缓存接收信息
			byte[] bytes = new byte[1024];
			// 创建一个解包器
			DatagramPacket dp1 = new DatagramPacket(bytes,bytes.length);
			// 接收包
			socket.receive(dp1);
			// 用字符串解包
			String str = new String(dp1.getData(), 0, dp1.getData().length);
			System.out.println("服务器说:"+str);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

/**
 * UDP服务器
 * @author 周太阳
 * @version 1.0
 * 2019年4月30日 下午2:43:37
 */
public class LoginServer {

	public static void main(String[] args) {
		// 创建一个缓存接收包
		byte[] receive = new byte[1024];
		// 创建一个解包器
		DatagramPacket dp = new DatagramPacket(receive, receive.length);
		try (
			// 创建一个接收器
			DatagramSocket ds = new DatagramSocket(5000);
			){
			// 接收包
			ds.receive(dp);
            // 用字符串解包
			String str = new String(dp.getData(),0,dp.getData().length);
			System.out.println("客户端说:"+str);
			
			// 给客户端发送信息
			String info = "一箱饮料";
			// 变成字节数组
			byte[] gift= info.getBytes();
			// 打包
			DatagramPacket dp1 = new DatagramPacket(gift,gift.length,dp.getSocketAddress());
			// 发送
			ds.send(dp1);
		} catch (Exception e) {
			// TODO: handle exception
		}
	}
}

猜你喜欢

转载自blog.csdn.net/Super_Robot/article/details/89747245