Java----网络编程 udp 实现一个基于udp协议的简单聊天功能

udp面向非连接,是一种传输层协议,提供面向事务的简单不可靠信息传送服务,例如视频聊天,游戏卡顿

由传输层到达应用层需要套接字  Socket

手写了一下模拟udp传输协议

注意端口不能重复

发送端:

package cn.net.java.mhz;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;

/**
 * 	 注意端口被占用的问题       同一个协议下端口不允许重复
 * udp编程:一切以包裹为中心
 * udp不安全,存在丢包,但是性能效率比较高
 * udp可能将一个数据分成多个数组来传输
 * udp发送端和接收端地位平等
 * 
 * DatagramSocket:用于发送或接收数据包的套接字
 * DatagreamPacket:数据包
 * 
 * @author MHZ
 * 
 * 基本流程:
 * 	发送端
 *1.使用DatagramSocket 指定端口   创建发送端
 * 2.准备容器  
 * 3.封装成DatagramPacket包裹,指定目的地
 * 4.发送包裹	  send
 *  5.释放资源
 *  
  *
 */
public class MyUDPSocket {
	public static void main(String[] args) throws Exception {
		System.out.println("发送方启动中........");
		//1.使用DatagramSocket 指定端口   创建接收端
		DatagramSocket client = new DatagramSocket(6666);
		//2.准备容器 把要传送的数据写成字节数组的形式
		String data = "MHZ";
		byte[] datas = data.getBytes();
		//3.封装成DatagramPacket包裹,指定目的地
		DatagramPacket packet = new DatagramPacket(datas,0,datas.length,new InetSocketAddress("localhost",8888));
		//4.发送包裹
		client.send(packet);
		// 5.释放资源
		client.close();
	}
}

接收端:

package cn.net.java.mhz;

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

/**
 * Udp编程
 * @author MHZ
 * 
 * 基本流程:
 * 接收端
 *1.使用DatagramSocket 指定端口   创建接收端
 * 2.准备容器  封装成DatagramPacket包裹
 * 3.阻塞式接收包裹
 * 4.分析数据
 *  byte[] getData()
 *         getLength()
 *  5.释放资源
 *
 */
public class MyUDPSocketSever {
	public static void main(String[] args) throws Exception {
		System.out.println("接收方启动中........");
		//1.使用DatagramSocket 指定端口   创建接收端
		DatagramSocket server = new DatagramSocket(8888);
		//2.准备容器  封装成DatagramPacket包裹
		byte[] container = new byte[1024*60];
		DatagramPacket packet = new DatagramPacket(container,0,container.length);
		//3.阻塞式接收包裹
		server.receive(packet);
		//4.分析数据
		byte[] datas = packet.getData();
		int len = packet.getLength();
		System.out.println(new String(datas,0,len));
		// 5.释放资源
		server.close();
	}
}

实现一个学生与老师的互动交流的聊天功能,一边作为发送端,一边作为接收端,需要用到多线程的知识

         首先要实现多次交流,使用到循环和控制台

package cn.net.java.mhz;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;

/**
 * 实现多次发送,多次接收
 * @author MHZ
 *
 */
public class UdpClientTalk {
	public static void main(String[] args) throws Exception {
		System.out.println("发送方启动中........");
		// 1.使用DatagramSocket 指定端口 创建接收端
		DatagramSocket client = new DatagramSocket(7777);
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		while (true) {
			// 2.准备容器 把要传送的数据写成字节数组的形式
			String data = br.readLine();
			byte[] datas = data.getBytes();
			// 3.封装成DatagramPacket包裹,指定目的地 地址+端口
			DatagramPacket packet = new DatagramPacket(datas, 0, datas.length,
					new InetSocketAddress("localhost", 9999));
			// 4.发送包裹
			client.send(packet);
			if(data.equals("bye")) {
				break;
			}
		}
		client.close();
		br.close();
	}
}
package cn.net.java.mhz;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

/**
 * 实现多次发送,多次接收
 * @author MHZ
 *
 */
public class UdpSeverTalk {
	public static void main(String[] args) throws Exception {

		System.out.println("接收方启动中........");
		// 1.使用DatagramSocket 指定端口 创建接收端
		DatagramSocket server = new DatagramSocket(9999);
		while (true) {
			// 2.准备容器 封装成DatagramPacket包裹
			byte[] container = new byte[1024 * 60];
			DatagramPacket packet = new DatagramPacket(container, 0, container.length);
			// 3.阻塞式接收包裹
			server.receive(packet);
			// 4.分析数据
			byte[] datas = packet.getData();
			int len = packet.getLength();
			String data = new String(datas, 0, len);
			System.out.println(data);
			if(data.equals("bye")) {
				break;
			}
		}
		// 5.释放资源
		server.close();
	}
}

接着实现两个多线程类,实现了Runnable接口,重写run方法,利用了上面写出的两个多次交流的类

       发送端:

package cn.net.java.mhz;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;

/**
 * 实现多线程的udp编程,实现一个简单的聊天功能
 * 发送端
 * @author MHZ
 *
 */
public class UdpTalkSend implements Runnable{
	private DatagramSocket client;
	private int port;
	private String toIP;
	private int toPort;
	private BufferedReader br;
	
	public UdpTalkSend(int port,String toIP,int toPort)
	{
		this.port = port;
		this.toIP = toIP;
		this.toPort = toPort;
		this.br = new BufferedReader(new InputStreamReader(System.in));
		try {
			client = new DatagramSocket(port);
		} catch (SocketException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	@Override
	public void run() {
		while (true) {
			// 2.准备容器 把要传送的数据写成字节数组的形式
			String data;
			try {
				data = br.readLine();
				byte[] datas = data.getBytes();
				// 3.封装成DatagramPacket包裹,指定目的地 地址+端口
				DatagramPacket packet = new DatagramPacket(datas, 0, datas.length,
						new InetSocketAddress(this.toIP, this.toPort));
				// 4.发送包裹
				client.send(packet);
				if (data.equals("bye")) {
					break;
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		//关闭资源
		this.client.close();
	}
}

       接收端:

package cn.net.java.mhz;

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

/**
 * 实现多线程的udp编程
 * 接收端
 * @author MHZ
 *
 */
public class UdpTalkReceive implements Runnable{
	// 1.使用DatagramSocket 指定端口 创建接收端
	private DatagramSocket server;
	private int port;
	private String from;
	
	public UdpTalkReceive(int port,String from)
	{
		this.port = port;
		this.from = from;
		try {
			this.server = new DatagramSocket(port);
		} catch (SocketException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	@Override
	public void run() {
		while (true) {
			// 2.准备容器 封装成DatagramPacket包裹
			byte[] container = new byte[1024 * 60];
			DatagramPacket packet = new DatagramPacket(container, 0, container.length);
			// 3.阻塞式接收包裹
			try {
				server.receive(packet);
				// 4.分析数据
				byte[] datas = packet.getData();
				int len = packet.getLength();
				String data = new String(datas, 0, len);
				System.out.println(this.from + ":" + data);
				if (data.equals("bye")) {
					break;
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}
		// 5.释放资源
		this.server.close();
	}
	
}

最后调用这两个类,实现功能并测试

package cn.net.java.mhz;
/**
 * 实现一个基于udp协议的在线咨询
 * @author MHZ
 *
 */
public class TalkStudent {
	public static void main(String[] args) {
		//多线程,学生既可以作为发送者,也可以作为接收者
		new Thread(new UdpTalkSend(2222,"localhost",5555)).start();		//作为发送者的线程
		
		new Thread(new UdpTalkReceive(1111,"老师")).start();			//作为接收者的线程
	}
}
package cn.net.java.mhz;
/**
 * 实现一个基于udp协议的在线咨询
 * @author MHZ
 *
 */
public class TalkTeacher {
	public static void main(String[] args) {
		new Thread(new UdpTalkReceive(5555,"学生")).start();
		
		new Thread(new UdpTalkSend(3333,"localhost",1111)).start();		//作为发送者的线程
	}
}

 

你可能感兴趣的:(JAVA学习)