Java网络编程——基于UDP的Socket编程

原创 2016年06月01日 11:35:50

一、基于UDP的Socket编程

1、UDP协议:UDP协议(用户数据协议)是无连接的、不可靠的、无序的通信协议,使用UDP进行通信不需要像TCP协议那样先建立连接,因此UDP的传输速率要快一些。UDP以数据报作为数据传输的载体,在使用UDP进行数据传输时,首先需要将数据封装数据报(Datagram),在数据报中指明数据所要到达的主机地址和端口号,再将数据报发送出去。

2、Java提供的基于UDP协议操作类有:DatagramPacket数据报类,DatagramSocket数据报通信类。


二、基于UDP的Socket实例

1、单线程情况下,服务器只与一个客户端通信

服务器端:

UDPServer.java

public class UDPServer {
	public static void main(String[] args) {
		try {
			//1、创建DatagramSocket对象,并绑定端口
			DatagramSocket socket = new DatagramSocket(9999);
			System.out.println("------我是服务器,准备接收客户端请求------");
			
			//2、定义数据报,用于接收客户端的信息
			byte[] data = new byte[1024];
			DatagramPacket packet = new DatagramPacket(data, data.length);
			//3、接收数据报,在接收到数据报之前该方法一直处于阻塞状态
			//数据报对象的 length 字段包含所接收信息的长度。如果信息比包的长度长,该信息将被截短。
			socket.receive(packet);
			
			String msg = new String(packet.getData(), 0, packet.getLength());
			System.out.println("收到客户端信息:" + msg);
			
			//4、定义向客户端发送信息的数据报,其中包含客户端的地址、端口信息
			InetAddress address = packet.getAddress();
			int port = packet.getPort();
			byte[] myMsg = new String("我是服务器,我已经收到了你的请求!").getBytes();
			DatagramPacket reply = new DatagramPacket(myMsg, myMsg.length, address, port);
			//5、向客户端发送数据报
			socket.send(reply);
			
			//6、关闭socket
			socket.close();
		} catch (SocketException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
客户端:

UDPClient.java

public class UDPClient {
	public static void main(String[] args) {
		try {
			//1、定义数据报的信息,包含数据、服务器的地址、端口等
			InetAddress address = InetAddress.getByName("localhost");
			System.out.println("------我是客户端,准备向服务器发送请求------");
			byte[] data = new String("我是客户端,你收到了我的请求吗?").getBytes();
			DatagramPacket packet = new DatagramPacket(data, data.length, address, 9999);
			
			//2、定义DataframSocket对象
			DatagramSocket socket = new DatagramSocket();
			//3、向服务器发送数据报信息
			socket.send(packet);
			
			//4、定义接收到服务器的数据报信息
			byte[] reciveMsg = new byte[1024];
			DatagramPacket reply = new DatagramPacket(reciveMsg, reciveMsg.length);
			//5、接收到服务器的响应
			socket.receive(reply);
			String msg = new String(reciveMsg, 0, reply.getLength());
			System.out.println("收到服务器应答:" + msg);
			
			//6、关闭socket
			socket.close();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (SocketException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

2、多线程情况下,一个服务器可以与多个客户端通信

服务器主类:

UDPServerThreadMain.java

public class UDPServerThreadMain {
	public static void main(String[] args) {
		try {
			DatagramSocket socket = new DatagramSocket(9999);
			byte[] data = new byte[1024];
			System.out.println("------服务器已经启动,准备接收客户端请求------");
			
			while(true) {
				//定义数据报一定要放在循环内,不然在第一次循环的时候将不输出数据,以后每次循环都将输出上次一循环的内容
				//如果写在循环外,因为socket.receive(packet)是synchronized的,会锁死对象packet,
				//主线程锁死packet对象后,在start()的子线程中不能调用  packet.属性,packet.方法()
				//如果卸载循环内,在while循环到第二次时,new了一个新的packet对象,主线程锁住新对象,上一次的对象自动解锁,
				//上一次循环时新建的子线程中的对packet进行调用的方法才可以开始执行。
				DatagramPacket packet = new DatagramPacket(data, 0, data.length);
				socket.receive(packet);
				UDPServerThread thread = new UDPServerThread(socket, packet, data);
				thread.start();
			}
		} catch (SocketException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}


服务器处理线程类:

UDPServerThread.java

public class UDPServerThread extends Thread {

	public byte[] data;
	
	public DatagramPacket packet;
	
	public DatagramSocket socket;
	
	public UDPServerThread(DatagramSocket socket, DatagramPacket packet, byte[] data) {
		this.socket = socket;
		this.packet = packet;
		this.data = data;
	}
	
	public void run() {
		System.out.println("收到客户端请求:" + new String(data, 0, packet.getLength()));
		
		byte[] msg = new String("我是服务器,我已经收到了你的请求!").getBytes();
		InetAddress address = packet.getAddress();
		int port = packet.getPort();
		DatagramPacket reply = new DatagramPacket(msg, msg.length, address, port);
		
		try {
			socket.send(reply);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
客户端代码与单线程情况下的客户端代码一样。




版权声明:本文为博主原创文章,未经博主允许不得转载。

Java网络编程实践和总结 --- 基于UDP的Socket编程

前面的blog介绍和总结基于TCP协议的网络编程。TCP提供了一种可靠的传输方式。如果数据在传输过程丢失或者损坏了,TCP会保证数据会再次发送,直到数据完整接受。如果数据包以乱序到达目的地,TCP也会...
  • joeyjobs
  • joeyjobs
  • 2015年04月02日 19:54
  • 1755

Java 基于UDP的Socket网络编程的入门及示例

前言:天呐!这两天上班就像走钢丝啊,老大家里出事请假一周,手机关机,底层无人照看,机器又忙着定标,技术盲老板事事问我这个底层小白。做人好难呐。。。还是祝愿老大家里没有大碍吧,也保佑自己明天能安然度过。...
  • u014158743
  • u014158743
  • 2016年10月25日 23:16
  • 947

TCP/UDP Socket编程步骤

sockets(套接字)编程有三种,流式套接字(SOCK_STREAM),数据报套接字(SOCK_DGRAM),原始套接字(SOCK_RAW); WINDOWS环境下TCP/UDP编程步骤: 1....
  • aizquan
  • aizquan
  • 2014年04月05日 15:40
  • 2415

赵雅智_java网络编程(4)TCP/IP、Http和Socket的区别

通过java网络编程(1)网络体系结构及通信协议我知道IP协议对应于网络层,TCP协议对应于传输层,而HTTP协议对应于应用层, 三者从本质上来说没有可比性 TPC/IP协议是传输层协议,主要解决...
  • zhaoyazhi2129
  • zhaoyazhi2129
  • 2014年10月24日 10:09
  • 1365

基于Socket实现网络编程

Socket是网络上两个程序间双向通讯的一端,它既可以发送请求,也可以接收请求,利用它可以方便的编写网络上数据的传递,在java中,有专门的类类处理用户的请求和响应。利用Socket 类的方法,就可以...
  • u012942818
  • u012942818
  • 2015年05月24日 17:40
  • 2227

(JAVA)基于Socket的TCP和UDP编程

(JAVA)基于Socket的TCP和UDP编程 最近空闲下来了,顺便学习了下Java的网络编程,例子都是来源网络,整理了下,先记录下来,以便后用! 一. TCP 、UDP、Scoket TCP: T...
  • colwer
  • colwer
  • 2016年07月12日 15:03
  • 1927

基于UDP协议的socket编程

============================================================================= 开发环境:windows 开发工具:VC...
  • ZhengNice
  • ZhengNice
  • 2016年05月16日 22:11
  • 972

基于TCP/IP和UDP协议的socket编程结构解析

1.套接字(socket) socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,都可以用“打开open –> 读写write/read –> 关闭close”模式来操作...
  • ZhengNice
  • ZhengNice
  • 2016年05月16日 21:45
  • 2334

Android 网络编程(1)——Socket编程So easy

总结: 1、服务器端监听阻塞,accept一直阻塞到建立连接成功 2、客服端创建Socket对象阻塞,一直阻塞到建立连接成功 3、客服端与服务器端通过Socket的输入流进行接收数据,输出流进行发送数...
  • Thanksgining
  • Thanksgining
  • 2015年02月06日 10:24
  • 8187

C/C++实现基于UDP的网络编程

在网络编程中,我们一般用UDP或者TCP这两种协议来进行编写网络应用程序,那叫UDP呢? UDP:UDP的简称是User Datagram Protocol,中文名是用户数据报协议,是OSI 参考模...
  • nonecode
  • nonecode
  • 2012年09月12日 17:04
  • 8431
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Java网络编程——基于UDP的Socket编程
举报原因:
原因补充:

(最多只允许输入30个字)