UDP协议和TCP协议

目录
1 UDP协议
2 TCP协议

1 UDP协议


UDP通讯协议的特点:

  • 将数据封装为数据包。面向无连接。
  • 每个数据包大小限制在64K。
  • 因为无连接,所以不可靠。
  • 因为不需要建立连接,所以速度快。
  • UDP通讯是不分服务端和客服端的,只分发送端和接收端

发送端的使用步骤:

  1. 建立UDP的服务
  2. 准备数据,把数据封装到数据包中发送。发送端的数据包要带上IP地址与端口号
  3. 调用UDP的服务,发送数据
  4. 关闭资源
/**
 1. 发送端
*/
public class Demo1Sender {
	public static void main(String[] args) throws IOException {
		// 建立UDP的服务
		DatagramSocket datagramSocket = new DatagramSocket();
		// 准备数据,把数据封装到数据包中
		String data = "这是我的第一个UDP的例子!";
		// 创建一个数据包
		DatagramPacket packet = new DatagramPacket(data.getBytes(), data.getBytes().length, InetAddress.getLocalHost(), 9090);
		// 调用UDP的服务发送数据包
		datagramSocket.send(packet);
		// 关闭资源-----实际上就是释放占用的端口号
		datagramSocket.close();
	}
}

接收端的使用步骤:

  1. 建立UDP的服务
  2. 准备空的数据包接收数据
  3. 调用UDP的服务接收数据
  4. 关闭资源
/**
* 接收端
*/
public class Demo1Receive {
	public static void main(String[] args) throws IOException {
		// 建立UDP的服务,并且要监听一个端口
		DatagramSocket socket = new DatagramSocket(9090);
		// 准备空的数据包用于存放数据
		byte[] buf = new byte[1024];
		DatagramPacket datagramPacket = new DatagramPacket(buf, buf.length);
		// 调用UDP的服务接收数据   receive() 是一个阻塞型方法,没有接收到数据包之前会一直等待。
		socket.receive(datagramPacket);  //  实际上是存储到了byte数组中了。
		System.out.println("接收端收到的数据:" + new String(buf, 0, datagramPacket.getLength())); // getLength() 获取数据包存储了几个字节
		// 关闭资源
		socket.close();
	}
}

在UDP协议中,有一个IP地址称作为广播地址,广播地址就是主机号为255的地址。给广播地址发送消息时,在同一个网络段的机器都可以接收到信息。

/*
* 群聊发送端
*/
public class ChatSender extends Thread {
	@Override
	public void run() {
		try {
			// 建立UDP的服务
			DatagramSocket socket = new DatagramSocket();
			// 准备数据,把数据封装到数据包中
			BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
			String line = null;
			DatagramPacket packet = null;
			while((line = bufferedReader.readLine()) != null) {
				// 把数据封装到数据包中
				packet = new DatagramPacket(line.getBytes(), line.getBytes().length, InetAddress.getByName("10.200.17.255"), 9092);
				// 发送数据
				socket.send(packet);
			}
			// 关闭资源
			socket.close();
		} catch(IOException e) {
			e.printStackTrace();
		}
	}
}
/**
* 群聊接收端
*/
public class ChatReceive extends Thread{
	@Override
	public void run() {
		try {
			// 创建UDP的服务
			DatagramSocket socket = new DatagramSocket(9092);
			// 准备空的数据包存储数据
			byte[] buf = new byte[1024];
			DatagramPacket packet = new DatagramPacket(buf, buf.length);
			boolean flag = true;
			while(flag) {
				socket.receive(packet);
				// packet.getAddress() 获取对方数据包的IP地址对象
				System.out.println(packet.getAddress().getHostAddress() + "说:" + new String(buf, 0 ,packet.getLength()));
			}
			// 关闭资源
			socket.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
public class ChatMain {
	public static void main(String[] args) {
		ChatReceive chatReceive = new ChatReceive();
		chatReceive.start();
		ChatSender chatSender = new ChatSender();
		chatSender.start();
	}
}

UDP是一个不可靠(数据包可能会丢失)的协议。

什么情况下数据包会出现丢失呢?

  • 带宽不足
  • CPU的处理能力不足

2 TCP协议


TCP通讯协议的特点:

  • TCP是基于IO流进行数据传输的,面向连接。
  • TCP进行数据传输时是没有大小限制的。
  • TCP是面向连接的,通过三次握手机制保证数据完整性。是可靠协议。
  • TCP是面向连接的,所以速度慢。
  • TCP是区分客户端与服务端的。

TCP的客户端使用步骤:

  1. 建立TCP的客户端服务
  2. 获取对应的流对象
  3. 写出或读取数据
  4. 关闭资源
public class Demo1Client {
	public static void main(String[] args) throws IOException {
		// 建立TCP的服务
		Socket socket = new Socket(InetAddress.getLocalHost(), 9090);
		// 获取到Socket对象的输出流对象
		OutputStream outputStream = socket.getOutputStream();
		// 利用输出流对象把数据写出即可
		outputStream.write("服务端你好!".getBytes());		

		// 获取输入流对象,读取服务端回送的数据
		InputStream inputStream = socket.getInputStream();
		byte[] buf = new byte[1024];
		int length = inputStream.read(buf);
		System.out.println("客户端接收到的数据:" + new String(buf, 0, length));
		// 关闭资源
		socket.close();
	}
}

ServerSocket的使用步骤:

  1. 建立TCP服务端的服务
  2. 接收客户端的连接产生一个Socket
  3. 获取对应的流对象读取或者写出数据
  4. 关闭资源
public class Demo1Server {
	public static void main(String[] args) throws IOException {
		// 建立TCP的服务端,并且监听一个端口
		ServerSocket serverSocket = new ServerSocket(9090);
		// 接收客户端的连接
		Socket socket = serverSocket.accept(); // accept() 接收客户端的连接,该方法也是一个阻塞的方法,没有客户端与其连接时,会一直等待下去。
		// 获取输入流对象,读取客户端发送的内容
		InputStream inputStream = socket.getInputStream();
		byte[] buf = new byte[1024];
		int length = inputStream.read(buf);
		System.out.println("服务端接收到的数据:" + new String(buf, 0, length));
		// 获取输出流对象,向客户端发送数据
		OutputStream outputStream = socket.getOutputStream();
		outputStream.write("客户端你好啊!".getBytes());
		// 关闭资源
		serverSocket.close();
	}
}

需求:客户端和服务端一问一答聊天。

/**
* 聊天的客户端
*/
public class ChatClient {
	public static void main(String[] args) throws IOException {
		// 建立TCP的客户端服务
		Socket socket = new Socket(InetAddress.getLocalHost(), 9090);
		// 获取键盘的输入流,读取数据
		BufferedReader keyReader = new BufferedReader(new InputStreamReader(System.in));
		// 获取Socket的输出流对象
		OutputStreamWriter socketOut = new OutputStreamWriter(socket.getOutputStream());
		// 获取Socket的输入流对象
		BufferedReader socketReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));		

		String line = null;
		// 不断地读取键盘的录入数据,然后把数据写出
		while((line = keyReader.readLine()) != null) {
			socketOut.write(line + "\r\n"); // 这里写一行数据时,是不会写到\r\n的(readLine方法不会读到\r\n),这样在服务端读一行数据时就读不到\r\n,导致读取数据失败
			// 刷新
			socketOut.flush();
			// 读取服务端回送的数据
			line = socketReader.readLine();
			System.out.println("服务端回送的数据:" + line);
		}
		// 关闭资源
		socket.close();
	}
}
/**
* 聊天的服务端
*/
public class ChatServer {
	public static void main(String[] args) throws IOException {
		// 建立TCP的服务端服务
		ServerSocket serverSocket = new ServerSocket(9090);
		// 接收客户端的连接,产生一个Socket
		Socket socket = serverSocket.accept();
		// 获取键盘的输入流对象
		BufferedReader keyReader = new BufferedReader(new InputStreamReader(System.in));
		// 获取Socket的输出流对象
		BufferedWriter keyOut = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
		// 获取到Socket的输入流对象
		BufferedReader socketReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
		// 读取客户端的数据
		String line = null;
		while((line = socketReader.readLine()) != null) {
			System.out.println("服务端接收到的数据:" + line);
			System.out.println("请输入服务端回送的数据:");
			line = keyReader.readLine();
			keyOut.write(line + "\r\n");
			keyOut.flush();
		}
		// 关闭资源
		serverSocket.close();
	}
}
  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值