Java网络编程

Java网络编程

网络编程:

网络编程:多台计算机互相传输数据。

计算机网络:

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

网络编程:

实现多台计算机之间实现数据的共享和传递。

网络应用程序主要组成为:网络编程 +IO流 +多线程(三大技术)。

网络模型:

网络模型:两台计算机之间的通信是根据什么规则来走的。

分为:OSI模型(理想中的模型)和TCP/IP模型(实际应用的模型)。
想深入学习的可以学习《TCP/IP详解》《TCP协议簇》书籍。

网络编程三要素:

网络通讯的模型:请求-响应,客户端-服务端。

三要素:IP地址端口协议(数据传输的规则)。

IP地址:

IP地址:网络中计算机的唯一标识 (IP地址是一个32位 的二进制数据,为了方便,将一个字节的二进制转换为一个十进制的数据)。

IP地址的组成:网络号段 +主机段
A类IP地址:第一段号码为网络号码,剩下的三段号码为本地计算机的号码----可以配置 256* 256 *256 台主机。

B类IP地址:前二段号码为网络号码,剩下的二段号码为本地计算机的号码。

C类IP地址:前三段号码为网络号码,剩下的一段号码为本地计算机的号码。
A类地址的表示范围为:0.0.0.0~126.255.255.255,默认网络屏蔽为:255.0.0.0;A类地址分配给规模特别大的网络使用。

A类网络用第一组数字表示网络本身的地址,后面三组数字作为连接于网络上的主机的地址。分配给具有大量主机(直接个人用户)而局域网络个数较少的大型网络。例如IBM公司的网络。

B类地址的表示范围为:128.0.0.0~191.255.255.255,默认网络屏蔽为:255.255.0.0;

C类地址的表示范围为:192.0.0.0~223.255.255.255,默认网络屏蔽为:255.255.255.0;C类地址分配给小型网络,如一般的局域网和校园网,它可连接的主机数量是最少的,采用把所属的用户分为若干的网段进行管理。
特殊地址:

127.0.0.1 回环地址,可用于测试本机的网络是否有问题。eg: ping 127.0.0.1

​ DOS命令 :ipconfig-------->查看本机IP地址

​ xxx.xxx.xxx.255 ------->广播地址

端口号:

端口号:正在运行的程序的标识
tips:

​ 1. 每个网络程序都会至少有一个逻辑端口。

​ 2. 用于标识进程的逻辑地址,不同进程的标识不同。

​ 3. 有效端口:0~65535,其中0~1024系统使用或保留端口。

​ 4. 通过第三方工具可以查看。
端口与协议有关:

​ TCP和UDP的端口互不相干,同一个协议的端口不能重复不同协议的端口号可以重复

协议:

协议:通信规则,就是数据的传输规则。
TCP 与 UDP区别:

​ TCP、UDP都是传输层的协议。

​ TCP:建立连接,形成传输数据的通道;在连接中进行大数据量 传输;通过三次握手完成连接,是可靠 协议;必须建立连接效率会稍低,例如:打电话。

​ UDP:将数据源和目的封装到数据包中, 需要建立连接 ;每个数据报的大小在限制在64k;因无连接,是不可靠协议 ;不需要建立连接,速度快:例如发短信。

区别 TCP UDP
是否连接 面向连接 无面向连接
传输可靠性 可靠 不可靠
应用场合 传输大量数据 少量数据
速度
TCP协议:

服务端和客户端交互。
TCP协议:建立连接,形成传输数据的通道;在连接中进行大数据量 传输;通过三次握手完成连接,是可靠 协议;必须建立连接效率会稍低,例如:打电话。

TCP三次握手 和 四次挥手:
三次握手:
四次挥手:
案例:
传输文件:
java 复制代码
//服务端
public class Server {

	public static void main(String[] args) throws IOException {
		
		ServerSocket server = new ServerSocket(8080);
		
		Socket socket = server.accept();
		
        //接收的文件
		BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
        //把接收的文件存入本地文件中
		BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("copy.mp4"));
		
		byte[] bs = new byte[1024];
		int len;
		while((len = bis.read(bs)) != -1){
			bos.write(bs, 0, len);
		}
		
		bis.close();
		bos.close();
		server.close();
	}
}
java 复制代码
//客户端
public class Client {
	public static void main(String[] args) throws UnknownHostException, IOException {
		
		Socket socket = new Socket("127.0.0.1", 8080);
		//准备发送的本地文件
		BufferedInputStream bis = new BufferedInputStream(new FileInputStream("Original.mp4"));
        //发送的文件
		BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
		
		byte[] bs = new byte[1024];
		int len;
		while((len = bis.read(bs)) != -1){
			bos.write(bs, 0, len);
		}
		
		bis.close();
		bos.close();
		socket.close();
	}
}
单聊:

只能一人一句话的来,只能客户端先发。

java 复制代码
//服务端
public class Server {

	public static void main(String[] args) throws IOException {
		
		ServerSocket server = new ServerSocket(8080);
		
		Socket socket = server.accept();
		
		Scanner scan = new Scanner(System.in);
		
        //接收的信息
		BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "GBK"));
        //发送的信息
		PrintStream ps = new PrintStream(socket.getOutputStream());
		
		while(true){
			String readLine = br.readLine();
			System.out.println(readLine);
			
			ps.println("小红:" + scan.next());
		}
		
	}
}
java 复制代码
//客户端
public class Client {
	public static void main(String[] args) throws UnknownHostException, IOException {
		
		Socket socket = new Socket("127.0.0.1", 8080);
		
		Scanner scan = new Scanner(System.in);
		
        //发送的信息
		PrintStream ps = new PrintStream(socket.getOutputStream());
        //接收的信息
		BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "GBK"));
		
		while(true){
			
			ps.println("小明:" + scan.next());
			
			String readLine = br.readLine();
			System.out.println(readLine);
		}
		
	}
}

优化单聊:一人可以多句话,随便谁先发。

发送消息在主线程,接受消息在子线程。

java 复制代码
//接收线程
public class ReceiveThread extends Thread{
	
	private Socket socket;
	
	public ReceiveThread(Socket socket) {
		this.socket = socket;
	}

	@Override
	public void run() {
		
		try {
            //接收的消息
			BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "GBK"));
			while(true){
                //输出接收的消息
				String readLine = br.readLine();
				System.out.println(readLine);
			}
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
java 复制代码
//服务端
public class Server {

	public static void main(String[] args) throws IOException {
		
		ServerSocket server = new ServerSocket(8080);
		
		Socket socket = server.accept();
		
		new ReceiveThread(socket).start();
		
		Scanner scan = new Scanner(System.in);
		PrintStream ps = new PrintStream(socket.getOutputStream());
		while(true){
			ps.println("小红:" + scan.next());
		}
		
	}
}
java 复制代码
//客户端
public class Client {
	public static void main(String[] args) throws UnknownHostException, IOException {
		
		Socket socket = new Socket("127.0.0.1", 8080);
		
		new ReceiveThread(socket).start();
		
		Scanner scan = new Scanner(System.in);
		PrintStream ps = new PrintStream(socket.getOutputStream());
		while(true){
			ps.println("小明:" + scan.next());
		}
		
	}
}
群聊:
java 复制代码
public class ReceiveThread extends Thread{
	
	private Socket socket;
	
	public ReceiveThread(Socket socket) {
		this.socket = socket;
	}

	@Override
	public void run() {
		
		try {
             //接收的消息
			BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "GBK"));
			while(true){
                //输出接收的消息
				String readLine = br.readLine();
				System.out.println(readLine);
			}
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
java 复制代码
public class ServerThread extends Thread{
	
	private Socket socket;
	
	public ServerThread(Socket socket) {
		this.socket = socket;
	}

	@Override
	public void run() {
		
		try {
			//接受当前客户端的消息
			BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "GBK"));
			while(true){
				String readLine = br.readLine();
				System.out.println(readLine);
				
				//发送给其他客户端消息
				Set<Entry<String,PrintStream>> entrySet = Server.map.entrySet();
				for (Entry<String, PrintStream> entry : entrySet) {
					String ip = entry.getKey();
					PrintStream ps = entry.getValue();
					
					if(!socket.getInetAddress().toString().equals(ip)){
                        //当前Socket的IP地址和容器里的IP地址不同的时候,
                        //输出当前Socket的接收的信息给其他客户端。
						ps.println(readLine);
					}
				}
			}
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
java 复制代码
//服务端
public class Server {
	
	public static final ConcurrentHashMap<String, PrintStream> map = new ConcurrentHashMap<>();

	public static void main(String[] args) throws IOException {
		
		ServerSocket server = new ServerSocket(8080);
		
		while(true){
            //接收客户端的连接,创建Socket对象。
			Socket socket = server.accept();
			
            //客户端ip地址
			String ip = socket.getInetAddress().toString();
            //打印流,当前Socket接收的信息,要发送给其他客户端的信息。
			PrintStream ps = new PrintStream(socket.getOutputStream());
            //放入容器中
			map.put(ip, ps);
			//每创建一个Socket对象,就创建一个服务端线程。
			new ServerThread(socket).start();
		}
		
	}
}
java 复制代码
//客户端
public class Client {
	public static void main(String[] args) throws UnknownHostException, IOException {
		
		Socket socket = new Socket("127.0.0.1", 8080);
		
		new ReceiveThread(socket).start();
		
		Scanner scan = new Scanner(System.in);
		PrintStream ps = new PrintStream(socket.getOutputStream());
		while(true){
			ps.println("小明:" + scan.next());
		}
		
	}
}
UDP协议:

客户端和客户端交互。
​ UDP协议:将数据源和目的封装到数据包中, 需要建立连接 ;每个数据报的大小在限制在64k;因无连接,是不可靠协议 ;不需要建立连接,速度快:例如发短信。

客户端之间收发数据:

tips:

  1. UDP协议的Socket是DatagramSocket。
  2. 7070表示的是自己的端口号,不是对方的端口号。
java 复制代码
public class Client01 {

	public static void main(String[] args) throws IOException {
		
		//自己的端口号
		DatagramSocket socket = new DatagramSocket(7070);
		
		//1.向客户端2发送数据
		byte[] buf = "今天天气真好!!!".getBytes();
        //对方的IP地址和端口号
		DatagramPacket p = new DatagramPacket(buf , 0, buf.length, InetAddress.getByName("127.0.0.1"), 8080);
        //发送数据
		socket.send(p);
		
		//4.接受来自客户端1的数据
		buf = new byte[1024];
        //接收1024字节的信息
		p = new DatagramPacket(buf , buf.length);
        //接收数据
		socket.receive(p);
        //去掉首尾空格。
		System.out.println(new String(buf).trim());
		
		socket.close();
	}
}
java 复制代码
public class Client02 {

	public static void main(String[] args) throws IOException {
		
		DatagramSocket socket = new DatagramSocket(8080);
		
		//2.接受来自客户端1的数据
		byte[] buf = new byte[1024];
		DatagramPacket p = new DatagramPacket(buf , buf.length);
		socket.receive(p);
		System.out.println(new String(buf).trim());
		
		//3.向客户端2发送数据
		buf = "那就好好睡一觉!".getBytes();
		p = new DatagramPacket(buf , 0, buf.length, InetAddress.getByName("127.0.0.1"), 7070);
		socket.send(p);
		
		socket.close();
	}
}
UDP案例 之 单聊:
java 复制代码
public class SendThread extends Thread{
	
	private String nickName;
	private String ip;
	private int port;
	private DatagramSocket socket;
	
	public SendThread(String nickName, String ip, int port, DatagramSocket socket) {
		this.nickName = nickName;
		this.ip = ip;
		this.port = port;
		this.socket = socket;
	}
	
	@Override
	public void run() {
		Scanner scan = new Scanner(System.in);
		while(true){
			byte[] buf = (nickName + ":" + scan.next()).getBytes();
			try {
				DatagramPacket p = new DatagramPacket(buf, buf.length, InetAddress.getByName(ip), port);
                //发送
				socket.send(p);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

}
java 复制代码
public class ReceiveThread extends Thread{
	
	private DatagramSocket socket;
	
	public ReceiveThread(DatagramSocket socket) {
		this.socket = socket;
	}

	@Override
	public void run() {
		while(true){
			byte[] buf = new byte[1024];
			DatagramPacket p = new DatagramPacket(buf , buf.length);
			try {
                //接收
				socket.receive(p);
				System.out.println(new String(buf).trim());
			} catch (IOException e) {
				e.printStackTrace();
			}
			
		}
	}
}
java 复制代码
public class Client01 {

	public static void main(String[] args) throws SocketException {
		
		DatagramSocket socket = new DatagramSocket(7070);
		
        //接收
		new ReceiveThread(socket).start();
        //发送
		new SendThread("小明", "127.0.0.1", 8080, socket).start();
	}
}
java 复制代码
public class Client02 {

	public static void main(String[] args) throws SocketException {
		
		DatagramSocket socket = new DatagramSocket(8080);
		
		new ReceiveThread(socket).start();
		new SendThread("小红", "127.0.0.1", 7070, socket).start();
	}
}
HTTP协议:
案例:
获取淘宝商品周边类别:
java 复制代码
public static void main(String[] args) throws IOException {
		
		String path = "https://suggest.taobao.com/sug?code=utf-8&q=%E8%80%90%E5%85%8B&callback=cb";
		
		//创建链接对象
		URL url = new URL(path);
		//获取HTTP协议连接对象
		HttpURLConnection connection = (HttpURLConnection) url.openConnection();
		
		//设置参数
		connection.setConnectTimeout(5000);//设置连接超时时间
		connection.setReadTimeout(5000);//设置读取数据超时时间
		connection.setDoInput(true);//设置是否允许使用输入流
		connection.setDoOutput(true);//设置是否允许使用输出流
		
		//获取响应状态码
		int code = connection.getResponseCode();
		if(code == HttpURLConnection.HTTP_OK){
			//输入流
			BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(),"UTF-8"));
			char[] cs = new char[1024];
			int len;
			while((len = br.read(cs)) != -1){
				System.out.println(new String(cs, 0, len));
			}
			
		}else if(code == HttpURLConnection.HTTP_NOT_FOUND){
			System.out.println("页面未找到");
		}
	}
下载图片:
java 复制代码
public static void main(String[] args) throws IOException {
		
		String path = "https://wx2.sinaimg.cn/mw690/e2438f6cly1hoo3qpm7vrj21111jk4mn.jpg";
		
		//创建链接对象
		URL url = new URL(path);
		//获取连接对象
		HttpURLConnection connection = (HttpURLConnection) url.openConnection();
		
		//设置参数
		connection.setConnectTimeout(5000);//设置连接超时时间
		connection.setReadTimeout(5000);//设置读取数据超时时间
		connection.setDoInput(true);//设置是否允许使用输入流
		connection.setDoOutput(true);//设置是否允许使用输出流
		
		//获取响应状态码
		int code = connection.getResponseCode();
		if(code == HttpURLConnection.HTTP_OK){
			//输入流
			BufferedInputStream bis = new BufferedInputStream(connection.getInputStream());
            //输出流
			BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("啦啦啦.jpg"));
			byte[] bs = new byte[1024];
			int len;
			while((len = bis.read(bs)) != -1){
				bos.write(bs, 0, len);
			}
			
			bis.close();
			bos.close();
			
		}else if(code == HttpURLConnection.HTTP_NOT_FOUND){
			System.out.println("页面未找到");
		}
		
		
		
	}

InetAddress类:

InetAddress类:表示主机类。

java 复制代码
public static void main(String[] args) throws UnknownHostException {
		
		//获取本机的IP地址
//		InetAddress localHost = InetAddress.getLocalHost();
//		System.out.println(localHost);
		
		//获取域名对应的服务器地址
//		InetAddress byName = InetAddress.getByName("www.baidu.com");
//		System.out.println(byName);
		
		//获取域名对应的所有的服务器地址
		InetAddress[] allByName = InetAddress.getAllByName("www.baidu.com");
		for (InetAddress inetAddress : allByName) {
			System.out.println(inetAddress);
		}
	}

一个域名 对应 多个IP地址。

Socket:

Scoket也叫套接字 ,其表示的是IP地址端口号 的组合。 网络编程主要就是指Socket编程,网络间的通信其实就是Socket间的通信,数据就通过IO流在两个Scoket间进行传递。

java 复制代码
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;

//服务端
public class Server {

	public static void main(String[] args) throws IOException {
		
		//前台
        //设置应用的端口号
		ServerSocket server = new ServerSocket(8080);
		
		//应用
		//注意:accept()是线程阻塞的方法,
        //该方法会等待客户端的连接成功后才生成一个Socket对象与之交互
		Socket socket = server.accept();
		
		//2.接受来自客户端的数据
        //InputStream in = socket.getInputStream();---->字节输入流
        //InputStreamReader isr = new InputStreamReader(in,"GBK");---->字符输入转换流(将字节流转换成字符流)
        //BufferedReader br = new BufferedReader(isr);---->带缓冲区的字符输入流
		BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "GBK"));
		String readLine = br.readLine();//读取一行
		System.out.println(readLine);
		
		
		//3.向客户端发送数据
		PrintStream ps = new PrintStream(socket.getOutputStream());
		ps.println("啦啦啦啦啦!!");
		
		br.close();
		ps.close();
		server.close();
	}
}
java 复制代码
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;

//客户端
public class Client {

	public static void main(String[] args) throws UnknownHostException, IOException {
		//服务端的IP地址和要连接的应用对应的端口号
		Socket socket = new Socket("127.0.0.1", 8080);
		
		//1.向服务端发送数据
        //OutputStream out=socket.getOutputStream();---->字节输出流
        //PrintStream ps = new PrintStream(out);---->字节打印流
		PrintStream ps = new PrintStream(socket.getOutputStream());
		ps.println("啦啦啦啦啦?");
		
		//4.接受来自服务端的数据
		BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "GBK"));
		String readLine = br.readLine();
		System.out.println(readLine);
		
		ps.close();
		br.close();
		socket.close();
	}
}

注意:关闭流相当于关闭Socket!

相关推荐
Re.不晚4 分钟前
Java入门15——抽象类
java·开发语言·学习·算法·intellij-idea
雷神乐乐10 分钟前
Maven学习——创建Maven的Java和Web工程,并运行在Tomcat上
java·maven
码农派大星。14 分钟前
Spring Boot 配置文件
java·spring boot·后端
顾北川_野21 分钟前
Android 手机设备的OEM-unlock解锁 和 adb push文件
android·java
江深竹静,一苇以航23 分钟前
springboot3项目整合Mybatis-plus启动项目报错:Invalid bean definition with name ‘xxxMapper‘
java·spring boot
weixin_4426434239 分钟前
推荐FileLink数据跨网摆渡系统 — 安全、高效的数据传输解决方案
服务器·网络·安全·filelink数据摆渡系统
confiself39 分钟前
大模型系列——LLAMA-O1 复刻代码解读
java·开发语言
Wlq041544 分钟前
J2EE平台
java·java-ee
XiaoLeisj1 小时前
【JavaEE初阶 — 多线程】Thread类的方法&线程生命周期
java·开发语言·java-ee
阑梦清川1 小时前
JavaEE初阶---网络原理(五)---HTTP协议
网络·http·java-ee