java 分别使用 tcp协议 和udp协议 完成客户端和服务器端的通信, socket 网络编程

一、什么是网络模型?

网络模型是对计算机网络的一种抽象描述和规范,用于解释网络中数据的传输、通信协议的工作方式以及网络中各个组件之间的关系。

常见的网络模型有 OSI 参考模型(Open Systems Interconnection Reference Model)和 TCP/IP 模型。OSI 参考模型将网络通信分为七层,分别是物理层、数据链路层、网络层、传输层、会话层、表示层和应用层。每一层都有特定的功能和职责。

TCP/IP 模型则通常分为四层,即网络接口层、网际层、传输层和应用层。

二、tcp协议和udp协议的区别?

TCP(Transmission Control Protocol,传输控制协议)和 UDP(User Datagram Protocol,用户数据报协议)主要有以下区别:

  1. 连接性:

    • TCP 是面向连接的协议,在通信之前需要建立连接,通信结束后要释放连接。
    • UDP 是无连接的协议,不需要事先建立连接,直接发送数据。
  2. 可靠性:

    • TCP 提供可靠的数据传输,通过确认、重传、拥塞控制等机制保证数据的正确和有序到达。
    • UDP 不保证数据的可靠交付,可能会出现丢包、乱序等情况。
  3. 有序性:

    • TCP 数据按发送顺序到达接收端。
    • UDP 不保证数据的顺序。
  4. 首部开销:

    • TCP 首部开销较大,因为包含了更多的控制信息来保证可靠性。
    • UDP 首部开销小,只有 8 个字节。
  5. 应用场景:

    • TCP 适用于对数据准确性和顺序要求较高的应用,如文件传输、电子邮件、远程登录等。
    • UDP 适用于实时性要求高、对少量丢包不敏感的应用,如视频直播、在线游戏、语音通话等。

三、使用UDP协议完成客户端和服务器端的通信案例

package com.daofeng;

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

/**  
 * @Title: UdpClient.java
 * @Description: 使用UDP协议完成客户端和服务器端的通信
 * @author HeLijin
 * @date 2024-11-04 13:54:33 
 */

//先写服务器端,再写客户端
public class UdpClient {
	public static void main(String[] args) throws IOException {
		System.out.println("udp客户端启动连接...");
		//不传入端口号,表示是客户端
		DatagramSocket ds = new DatagramSocket();
		
		String str = "刀锋网络";
		byte[] strBytes = str.getBytes();
		DatagramPacket dp = new DatagramPacket(strBytes, strBytes.length,InetAddress.getByName("127.0.0.1"), 8080);
		ds.send(dp);
		ds.close();
	}
}

package com.daofeng;

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

/**
 * http 浏览器 访问不了udp协议,因为 http底层采用的是tcp协议
 */
// udp服务器端 
public class UdpServer {
	public static void main(String[] args) throws IOException  {
		//1.ip地址+端口号
		System.out.println("udp服务已经启动...");
		//创建服务器端 端口号,默认使用本机Ip地址
		DatagramSocket ds = new DatagramSocket(8080);
		//服务器端接收客户端1024个字节
		byte[] bytes = new byte[1024];
		//定义数据包
		DatagramPacket dp = new DatagramPacket(bytes, bytes.length);
		//接收客户端请求,将数据封装到数据包
		//receive() 方法 如果客户端不向服务器端发送请求,就一直阻塞
		ds.receive(dp);
		System.out.println("来源IP地址:" + dp.getAddress() +",请求来源端口号:" +dp.getPort());
		String result = new String(dp.getData(),0,dp.getLength());
		System.out.println(result);
		//关掉服务器端端口号
		ds.close();
	}
}

四、使用 tcp协议 完成客户端和服务器端的通信

package com.daofeng;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**  
 * @Title: TcpClient.java
 * @Description: tcp协议 完成客户端和服务器端的通信
 * @author HeLijin
 * @date 2024-11-04 16:03:23 
 */
class TcpServer {
	public static void main(String[] args) throws IOException {
		System.out.println("tcp协议服务器端启动...");
		//缓存线程池创建线程
		ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
		//创建服务器端连接
		ServerSocket serverSocket = new ServerSocket(8080);
		try {
			// 设置多个客户端访问,支持并发访问
			while(true) {
				//接收客户端请求 有阻塞功能
				Socket accept = serverSocket.accept();
				newCachedThreadPool.execute(new Runnable() {
					@Override
					public void run() {
						try {
							InputStream inputStream = accept.getInputStream();
							//将字节流转换成String类型
							byte[] bytes = new byte[1024];
							int len = inputStream.read(bytes);
							String result = new String(bytes, 0, len);
							System.out.println(Thread.currentThread().getName() + "服务器端接收到客户端内容:" + result);
							
							//响应客户端
							OutputStream outputStream = accept.getOutputStream();
							outputStream.write("this is daofeng.com".getBytes());
						} catch (Exception e) {
							// TODO: handle exception
						}
					}
				});
			}
		} catch (Exception e) {
			// TODO: handle exception
		} finally {
			serverSocket.close();
		}
	}
}
//客户端
public class TcpClient {
	public static void main(String[] args) throws IOException{
		System.out.println("socket tcp客户端启动...");
		//创建socket客户端
		Socket socket = new Socket("127.0.0.1", 8080);
		OutputStream outputStream = socket.getOutputStream();
		outputStream.write("我是刀锋网络忠实粉丝...".getBytes());
		socket.close();
	}
}

五、彩蛋

TCP 协议在建立连接时采用三次握手,在关闭连接时采用四次挥手。

采用三次握手成功之后,才开始进行数据传输。

在 TCP 三次握手过程中,相关参数的变化如下:

第一次握手:

  • 客户端发送一个 SYN 包给服务器,其中序列号(sequence number)通常是一个随机生成的数,假设为 J。

第二次握手:

  • 服务器收到客户端的 SYN 包后,向客户端发送一个 SYN + ACK 包。其中,序列号为服务器随机生成的一个数,假设为 K,确认号(ACK number)设置为客户端发送的序列号 J + 1,即 ACK = J + 1。

第三次握手:

  • 客户端收到服务器的 SYN + ACK 包后,向服务器发送一个 ACK 包。序列号为客户端第一次发送的序列号 J + 1,确认号为服务器第二次发送的序列号 K + 1,即 ACK = K + 1。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值