Java基础(十四)——UDP/TCP

网络编程

网络编程就是不同机器间的数据传输
电脑要上网必须有网线,网线是由网卡支持(硬件上)
每一个网卡有一个全球唯一的mac地址
网卡的物理地址通常是由网卡生产厂家烧入网卡中
它存储的是传输数据时真正赖以标识发出数据的电脑和
						接收数据的主机的地址
在网络底层的物理传输过程中,是通过物理地址来识别主机的

IP协议:进行IP数据包的分割和组装
ip地址是可变的
1.为每一台计算机分配IP地址
2.确定哪些地址在同一个子网络
ip地址是服务商给你的,mac地址是你的网卡物理地址
arp协议:通过接受到的ip解析出对应的mac地址完成两台机器的通信
IP地址属于网络层,而MAC地址属于数据链路层

数据链路层协议可以使数据从一个节点传递到相同链路
的另一个节点(通过MAC地址)

网络层协议使数据可以从一个网络传递到另一个网络上
(ARP根据目的IP地址,找到中间节点的MAC地址,
通过中间节点传送,从而最终到达目的网络)

一个主机与另一个主机连接需要ip地址与mac地址经过一系列的协议和节点
才能联通,相互之间收发数据还需要主机上的应用来完成(例如QQ,飞秋等)
应用的启动就需要系统为这个应用开辟一个端口(例如mysql数据库默认端口为3306)
通过ip与端口就可以找到主机上的应用从而进行通信了

有了唯一的mac地址为什么还要有ip地址?(源自百度)
由于全世界存在着各式各样的网络,他们使用不同的硬件地址。
要使这些异构网络能够互相通信就必须进行 非常复杂的硬件地址转化
工作,因此由用户或用户主机来完成这项工作几乎是不可能的的事。
但IP编址就把这个复杂的问题解决了。连接到互联网的主机
只需要各自拥有一个唯一的IP地址,他们之间的通信就像连接在
同一个网络那么简单方便。因为ARP是由计算机软件自动进行的
,对用户来说是看不见这种调用过程的。

UDP协议

一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务
UDP提供了无连接通信,且不对传送数据包进行可靠性保证,
适合于一次传输少量数据,UDP传输的可靠性由应用层负责
//server端(简略)
package server;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class UDPServer {
	public static void main(String[] args) throws IOException {
		// 创建数据收发对象
		DatagramSocket data = new DatagramSocket(3366);
		// 创建字节数组接收发送的数据
		byte[] b = new byte[1024];
		while (true) {
			// 创建数据封装对象
			DatagramPacket packet = new DatagramPacket(b, b.length);
			// 接收数据
			data.receive(packet);
			//获取客户端ip
			String ip = packet.getAddress().getHostAddress();
			//获取客户端端口
			int port = packet.getPort();
			// 获取要接收数据的字节长度
			int len = packet.getLength();
			//这一次存入的数据会覆盖数组中上一次存入的数据
			//无法覆盖全部的数组长度时,剩下无法覆盖的数据仍旧在数组中
			//只获取新存入数组的一部分数据
			String string = new String(b, 0, len);
			System.out.println(string + "..." + ip + " " + port);
			System.out.println(string.length());
		}
	}
}

//client(简略)
		DatagramSocket data = new DatagramSocket();
		InetAddress address = InetAddress.getByName("127.0.0.1");
		while (true) {
			Scanner scanner = new Scanner(System.in);
			String string = scanner.next();
			byte[] buf = string.getBytes();
			DatagramPacket da = new DatagramPacket(buf, buf.length, address, 3366);
			data.send(da);

		}

TCP协议

在主机间建立一个虚拟连接,以实现高可靠性的数据包交换
(ip协议与arp协议只能找对应的主机,不能保证通信的可靠性)
一个应用程序通过TCP协议与另一个程序通信时,先进行三次握手后,
在建立一个双方之间建立一个连接,所有数据就在这个连接中传递
每一次收到信息都会进行反馈,表示这个信息我收到了,
因此TCP是非常可靠的
连接断开需要四次挥手
//server-接收图片
public static void main(String[] args) throws IOException {
		//绑定主机端口
		ServerSocket server = new ServerSocket(9968);
		// 监听客户端请求,获取Socket对象
		Socket accept = server.accept();
		// 获取输入流读取数据
		InputStream in = accept.getInputStream();
		File file = new File("D:\\jpg");
		if (!file.exists()) {
			file.mkdirs();
		}
		// 创建输出流写入数据
		String filename = System.currentTimeMillis() + new Random().nextInt(100) + ".jpg";
		FileOutputStream output = new FileOutputStream(file + File.separator + filename);
		byte[] b = new byte[1024];
		int len = 0;
		while ((len = in.read(b)) > 0) {
			output.write(b, 0, len);
		}

		// 向客户端发送数据
		OutputStream out = accept.getOutputStream();
		// 输出数据
		out.write("上传成功! 	".getBytes());
		// 关闭资源
		output.close();
		out.close();
		in.close();
		accept.close();
		server.close();
	}
//client-上传图片
public static void main(String[] args) throws IOException {
		// 绑定服务器的IP和端口,并发送连接到服务器获取Socket对象
		Socket socket = new Socket("127.0.0.1", 9968);
		// 获取输出流
		OutputStream out = socket.getOutputStream();
		FileInputStream fileIn = new FileInputStream("D:\\图片\\2.jpg");
		byte[] b = new byte[1024];
		int len = 0;
		while ((len = fileIn.read(b)) > 0) {
			out.write(b, 0, len);
		}
		// 给服务器一个终止序列,不然服务端的while的read方法会造成阻塞
		socket.shutdownOutput();

		// 获取输入流
		InputStream in = socket.getInputStream();
		// 读取反馈数据
		byte[] by = new byte[1024];
		int lens = in.read(by);// 读取的数据长度
		System.out.println(new String(by, 0, lens));
		// 关闭资源
		fileIn.close();
		in.close();
		out.close();
		socket.close();
	}

服务端可以运用多线程接收请求

//线程类
public class TCPRunable implements Runnable {
	private Socket accept;

	public TCPRunable() {
		super();
	}

	public TCPRunable(Socket accept) {
		super();
		this.accept = accept;
	}

	@Override
	public void run() {
		// 获取输入流读取数据
		InputStream in;
		try {
			// 获取输入流读取数据
			in = accept.getInputStream();
			File file = new File("D:\\jpg");
			if (!file.exists()) {
				file.mkdirs();
			}
			// 创建输出流写入数据
			String filename = System.currentTimeMillis() + new Random().nextInt(100) + ".jpg";
			FileOutputStream output = new FileOutputStream(file + File.separator + filename);
			byte[] b = new byte[1024];
			int len = 0;
			while ((len = in.read(b)) > 0) {
				output.write(b, 0, len);
			}

			// 向客户端发送数据
			OutputStream out = accept.getOutputStream();
			// 输出数据
			out.write("上传成功! 	".getBytes());
			// 关闭资源
			output.close();
			out.close();
			in.close();
			accept.close();

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

}
//server
public static void main(String[] args) throws IOException {
		ServerSocket server = new ServerSocket(9968);
		while (true) {
			// 监听客户端请求,获取客户端Socket对象
			Socket accept = server.accept();
			new Thread(new TCPRunable(accept)).start();
		}

二者区别是:

1、连接方面区别
TCP面向连接
UDP是无连接的,即发送数据之前不需要建立连接。
2、安全方面的区别
TCP提供可靠的服务,通过TCP连接传送的数据,无差错,不丢失,不重复
UDP不保证数据可靠性,可能会造成数据出错。
3、传输效率的区别
TCP要保证数据可靠,所以传输效率相对较低。
UDP不保证数据可靠,所以传输效率高
发布了30 篇原创文章 · 获赞 0 · 访问量 353

猜你喜欢

转载自blog.csdn.net/qq_31241107/article/details/104697105