Java学习—网络编程(UDP)

这个篇博客来介绍一下用UDP协议进行网络编程。

UDP协议是一种面向无连接的协议。简单来说,它是类似的一个邮局系统(或者可以用发短信的原理去理解)。有收件人和发件人,发件人可以直接发送邮件,不关心收件人是否可以收到。而收件人则当知道有邮件过来时去拿即可,也不需要告知发件人是否收到。在早期QQ视频聊天中就采用的是UDP协议。这种协议的延迟比较少,但是可能会出现丢失数据报的情况。这种特性比较适合那些要求实时性强而不需要保证正确性的应用程序,如视频电话会议系统。想要进一步了解UDP协议的话可以自行查找资料。

学习UDP协议的网络编程依然是通过一个实例来学习,这个实例可能涉及到一点多线程的技术,这个技术在以后的博客中会讲解到。示例程序的需求是实现一个简单的聊天程序。

首先介绍一下应用的几个重要的java.net包中的用于UDP传输的几个类。

InetAddress:用于表示互联网协议的IP地址。此类中有很多静态方法,可以直接使用。getByName(String host),个顶主机名去顶主机的ip地址,返回值的是InetAdress类型。

DatagramPacket:用于表示数据包。用来实现无连接的数据包的投递,根据包中所包含的信息从一台机器路由到另一台机器。期间可能会选择不同的路由器,也不能保证安发送顺序到达。示例中主要用到了它的两种构造方法:DatagramPacket(byte[] buf, int  length),用来接收长度为length的数据报;DatagramPacket(byte[] buf, int length, InetAddress address, int port),用来将长度为length的数据包发送到指定主机的指定端口号上。

DatagramSocket:用于发送和接收数据包的套接字(Socket)。主要的方法有发送方法:sent(DatagramPacket p)。接收方法:receive(DatagramPacket p),这个是阻塞式的方法,即当没有收到数据时一直在这里等待,知道有数据来为止。

程序思路。对于发送端来说,首先要接收控制台的输入的数据并将其封装到数据包中,通过DatagramSocket的发送功能把包发送出去,发送端需要循环输入,并设定好退出的条件。对于接收端来说,通过DatagramSocket的接收功能接收到数据报,再用数据包类的功能解析出包中所含的信息。程序代码如下:

package lzl.udp.demo.chat;

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

class Send implements Runnable
{
	private DatagramSocket ds;
	private static final int SENDPORT = 8088;
	
	public Send(DatagramSocket ds)
	{
		this.ds = ds;
	}
	
	public void run()
	{
		try
		{
			//read the input data
			BufferedReader br = new BufferedReader(
									new InputStreamReader(
											System.in));
			String readLine = null;
			//read input always, but break out of the loop when read "quit" 
			while(null != (readLine = br.readLine()))
			{
				if("quit".equalsIgnoreCase(readLine))
					break;
				
				byte[] buf = readLine.getBytes();
				
				//encapsulated the data into a DatagramPacket
				DatagramPacket dp = new DatagramPacket(buf, 
													   buf.length, 
													   InetAddress.getByName("127.0.0.1"),
													   SENDPORT);
				//send the packet
				ds.send(dp);
			}
			
			ds.close();
		}catch(Exception e)
		{
			e.printStackTrace();
		}
	}
}

class Receive implements Runnable
{
	private DatagramSocket ds;
	private static final int SIZE = 1024;
	
	public Receive(DatagramSocket ds)
	{
		this.ds = ds;
	}
	
	public void run()
	{
		try
		{
			while(true)
			{
				byte[] buf = new byte[SIZE];
				DatagramPacket dp = new DatagramPacket(buf, buf.length);
				//receive the packet
				ds.receive(dp);
				
				String dataIP = dp.getAddress().getHostAddress();
				String data = new String(dp.getData(), 0, dp.getLength());
				
				System.out.println(dataIP + " : " + data);
			}
		}catch(Exception e)
		{
			e.printStackTrace();
		}
	}
}

public class UdpChatDemo
{
	public static void main(String[] args) throws Exception
	{
		//private final int LISTENPORT = 8088;
		final int LISTENPORT = 8088;
		DatagramSocket sendSocket = new DatagramSocket();
		DatagramSocket receiveSocket = new DatagramSocket(LISTENPORT);
		
		new Thread(new Send(sendSocket)).start();
		new Thread(new Receive(receiveSocket)).start();
	}
}

程序中main方法中注释掉了一行(第90行),这一行犯了一个比较低级的错误。错误提示是“illegal modifier for parameter ×××, only final is permittedpublic/private/protected是声明做用域的,放在类中时修饰方法或这一个域,而方法内部定义的变量只能在方法内部使用(做参数传出不算),在这里声明作用域无意义,也就禁止声明public/private/protected。所以说在方法内部声明变量只能在需要的时候用final修饰符修饰,除此之外不能用其它修饰符修饰,包括static都不能修饰变量。

这篇关于应用UDP协议进行网络编程的博客内容就讲这多,后面还有后续的一些关于网络编程的博客


参考资料:

1. JDK1.7 API:http://docs.oracle.com/javase/7/docs/api/

2. Java编程思想(第四版)

3. Java核心技术 卷1/卷2

4. 传智播客毕向东Java基础视频教程

5. 错误提示的分析参考:http://blog.csdn.net/ccccdddxxx/article/details/8051201


说明:

如有错误还请各位指正,欢迎大家一起讨论给出指导。

上述程序完整代码的下载链接:
https://github.com/zeliliu/BlogPrograms/tree/master/Java%E5%AD%A6%E4%B9%A0/udp_chat_demo

最后更新时间:2013-04-19

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以回答这个问题。UDP是一个无连接的协议,它不保证数据包的可靠传输,也不保证数据包的顺序。因此,在使用UDP进行网络通信时,需要注意以下几点: 1. UDP数据包的大小是有限制的,一般情况下不能超过64K。 2. 接收UDP数据包时,需要使用一个固定大小的缓冲区,来存储接收到的数据。如果数据包的大小超过了缓冲区的大小,那么多余的数据将被丢弃。 3. 接收UDP数据包时,需要使用一个循环来不断地接收数据,直到接收到完整的数据包为止。 下面是一个简单的Java UDP接收程序的示例代码: ```java import java.net.*; public class UDPReceiver { public static void main(String[] args) { try { DatagramSocket socket = new DatagramSocket(9999); byte[] buffer = new byte[1024]; DatagramPacket packet = new DatagramPacket(buffer, buffer.length); while (true) { socket.receive(packet); String message = new String(packet.getData(), 0, packet.getLength()); System.out.println("Received message: " + message); } } catch (Exception e) { e.printStackTrace(); } } } ``` 在这个示例程序中,我们创建了一个DatagramSocket对象,并绑定到了本地的9999端口。然后我们创建了一个缓冲区,用来存储接收到的数据。接着,我们创建了一个DatagramPacket对象,用来接收数据。在循环中,我们使用socket.receive()方法来接收数据包,并将数据存储在packet对象中。最后,我们将接收到的数据转换成字符串,并输出到控制台上。 希望这个示例程序可以帮助你理解UDP网络通信的基本原理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值