Socket之UDP通信

简单记之,留后用

先实现一对一通信

服务器类

public class UDPServer {

	public static void main(String[] args) throws IOException {
		
		/*
		 * 服务器接收数据
		 */
		//创建DatagramSockte对象,并指定端口号
		DatagramSocket socket=new DatagramSocket(8800);
		//设定接收的字节数组,大小可以任意,
		byte[] bs=new byte[1024];
		//创建数据报,并将接收的数组传入其中,大小为整个数组的长度
		DatagramPacket datagramPacket=new DatagramPacket(bs, bs.length);
		//接收,相当于监听,直到有数据报,开始响应,并将数据写入到字节数组中
		socket.receive(datagramPacket);
		//输出字节数组,长度为datagramPacket实际接收的长度
		System.out.println("客户端->服务器:"+new String(bs, 0, datagramPacket.getLength()));
		
		/*
		 * 服务器发送数据
		 */
		//因为是服务器向客户端发送数据,因此要知道客户端的IP地址,和通信的端口号(通过客户端发送的数据报获得)
		InetAddress inet=datagramPacket.getAddress();
		int port=datagramPacket.getPort();
		//要发送的字节数组
		byte[] bs2="welcome".getBytes();
		//将IP,端口号,字节数组写入到Datagrampacket对象中
		DatagramPacket datagramPacket2=new DatagramPacket(bs2, bs2.length, inet, port);
		//发送数据报
		socket.send(datagramPacket2);
		
		//最后别忘了关闭DatagramSocket对象
		socket.close();
	}
}

客户端类

public class UDPClient {

	public static void main(String[] args) throws IOException {
		/*
		 * 客户端发送数据
		 */
		//获取服务器的IP地址,这里是因为服务器就是本机,因此直接使用字符串形式的localhost
		InetAddress iAddress=InetAddress.getByName("localhost");
		int port=8800;
		byte[] bs="登入名:admin;密码:1234".getBytes();
		//创建数据报
		DatagramPacket datagramPacket=new DatagramPacket(bs, bs.length, iAddress,port);
		//创建DatagramSocket对象
		DatagramSocket socket=new DatagramSocket();
		//使用socket发送数据报
		socket.send(datagramPacket);
		
		/*
		 * 客户端接收数据
		 */
		//设定接收数据的字节数组
		byte[] bs2=new byte[1024];
		//创建接收的数据报
		DatagramPacket datagramPacket2=new DatagramPacket(bs2, bs2.length);
		//将接收的数据报赋给之前创建的数据报对象
		socket.receive(datagramPacket2);
		//输出数据
		System.out.println("服务器->客户端:"+new String(bs2, 0, datagramPacket2.getLength()));
		
		//关闭socket
		socket.close();
		
	}
}

多线程通信

给出比较正规的

服务器类

public class UDPServer {

	private static int j=0;
	
	public static void main(String[] args) throws IOException {
		
		/*
		 * 服务器接收数据
		 */
		//创建DatagramSockte对象,并指定端口号
		DatagramSocket socket=new DatagramSocket(8800);
		//设定接收的字节数组,大小可以任意,
		byte[] bs=new byte[1024];
		//接收,相当于监听,直到有数据报,开始响应,并将数据写入到字节数组中
		while(true){
			//创建数据报,并将接收的数组传入其中,大小为整个数组的长度
			DatagramPacket packet=new DatagramPacket(bs, bs.length);
	    	socket.receive(packet);
	    	UDPServerThread serverThread=new UDPServerThread(socket,packet);
	    	serverThread.start();
	    	
		}
		
	}

服务器线程类

public class UDPServerThread extends Thread{

	DatagramSocket socket=null;
	DatagramPacket packet=null;
	private static int i=0;
	
	public UDPServerThread(DatagramSocket socket,DatagramPacket packet) {
		// TODO Auto-generated constructor stub
		this.socket=socket;
		this.packet=packet;
	}
	
	@Override
	public void run() {

		//接收数据
		        byte[] bs=packet.getData();
		        //输出字节数组,长度为datagramPacket实际接收的长度
		        System.out.println("客户端->服务器:"+new String(bs, 0, packet.getLength()));
		       
		        
		        /*
				 * 服务器发送数据
				 */		
		        //因为是服务器向客户端发送数据,因此要知道客户端的IP地址,和通信的端口号(通过客户端发送的数据报获得)

		
		        InetAddress inet=packet.getAddress();
				int port=packet.getPort();
				//要发送的字节数组
				byte[] bs2=("welcome"+(++i)).getBytes();
				//将IP,端口号,字节数组写入到Datagrampacket对象中
				DatagramPacket datagramPacket2=new DatagramPacket(bs2, bs2.length, inet, port);
				//发送数据报
			    try {
					socket.send(datagramPacket2);
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}		
				//最后别忘了关闭DatagramSocket对象
//				socket.close();
	}
}

这里我之前在写的时候,出现了一个很奇妙的问题,我找了好久,错误代码如下

public static void main(String[] args) throws IOException {
		//创建DatagramSockte对象,并指定端口号
		DatagramSocket socket=new DatagramSocket(8800);
		//设定接收的字节数组,大小可以任意,
		byte[] bs=new byte[1024];
		//创建数据报,并将接收的数组传入其中,大小为整个数组的长度
		DatagramPacket packet=new DatagramPacket(bs, bs.length);
		//接收,相当于监听,直到有数据报,开始响应,并将数据写入到字节数组中
		while(true){
	    	socket.receive(packet);
	    	UDPServerThread serverThread=new UDPServerThread(socket,packet);
	    	serverThread.start();
	    	
		}
		
	}

因为DatagramPacket对象只有一个,每当new一个线程的时候,主线程里面就进入receive的堵塞状态,而且占据着这唯一的DatagramPacket对象,因此子线程中就不能够使用该对象,

后面意识到后,加了一句serverThread.join();  目的是让子线程先执行完后,主线程才开始进行堵塞状态,然后问题就解决了,但是这样会比前面介绍的运行慢



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值