udp socket java_[转载]基于UDP协议的Socket JAVA编程

本文详细介绍了基于UDP协议的Socket编程,包括UDP协议的特点、DatagramPacket类和DatagramSocket类的使用,以及如何进行UDP数据报的发送和接收。通过示例展示了如何创建服务器端和客户端程序,实现简单的时间同步和点对点聊天功能。
摘要由CSDN通过智能技术生成

基于UDP协议的Socket编程

1 UDP协议

2 DatagramPacket类和DatagramSocket类

2.1 DatagramPacket类

2.2 DatagramSocket类

3 基于UDP协议的Socket编程

3.1基于UDP协议的Socket编程的基本步骤

3.2 应用举例、本章小结

1

UDP协议

用户数据报协议(UserDatagramProtocol,UDP)是OSI参考模型中一种面向无连接的传输层协议,提供面向操作的简单的不可靠数据传送服务。在网络中它与TCP协议一样用于处理数据包。UDP协议直接工作于IP协议的顶层。

UDP协议在发送数据时并不刻意追求数据包会完全发送出去,也不能担保它们抵达的顺序与它们发出时一样,因为它是一种不可靠协议。

UDP协议的特性:

(1)UDP是一个面向无连接的协议,传输数据之前客户端和服务器端不建立连接,当它想发送数据时则获取来自应用程序的数据,并尽可能快地把它放到网络上。

(2)由于传输数据时不需建立连接,不需维护连接状态,因此一台服务器可同时向多个客户传输相同的数据。

UDP使用的类

DatagramPacket类包含具体的要传输的信息,这些信息被封装在称为数据报(Datagram)的UDP包中。

DatagramSocket类用于收发UDP数据报。

为发送数据,要将数据封装到DatagramPacket中,使用DatagramSocket发送该包。

为接收数据,要从DatagramSocket中接收一个DatagramPakcet对象,然后解析该包的内容。

UDP与TCP的比较

(1)UDP没有两台主机间唯一连接的概念。使用UDP时,每个数据报中都给出了完整的地址信息,因此无需要建立发送方和接收方的连接。对于TCP协议,由于它是一个面向连接的协议,在Socket之间进行数据传输之前必然要建立连接,所以在TCP中多了一个连接建立的时间。

(2)一个DatagramSocket可以从多个独立主机接收数据,也可向多个主机传输相同的数据,此Socket并不专用于一个连接。

(3)TCP

Socket将网络视为流,通过与Socket相关的输入输出流来收发数据。而UDP所处理的总是单个数据报包,封装在一个数据报中的数据都以一个包的形式整体收发,一个包不需与其它包相关。流中的数据是有序的,而数据报包与数据报包之间是无序的。

(4)使用UDP传输数据时是有大小限制的,每个被传输的数据报必须限定在64KB之内。而TCP没有这方面的限制,一旦连接建立起来,双方的socket就可以按统一的格式传输大量的数据。

2

DatagramPacket类和DatagramSocket类

 2.1DatagramPacket类

该类表示一个数据报包。该数据报包用来实现一个无连接包的传送服务。它是进行数据报通信的基本单位。包含了IP地址、端口号和需要传输的数据等。在发送和接收数据报时,要创建DatagramPakcet类对象作为数据的载体。

1.构造函数

(1)public DatagramPacket(byte ibuf[],int

ilength)

功能:创建一个用于接收数据报的DatagramPacket类对象。

参数:

ibuf:存储数据报的缓冲区。在数据报通信中,发送和接收一个数据报,都需提供一个缓冲区,用来安置发送和接收到的数据报。

 ilength:接收数据报的长度,必须小于等于ibuf.length。

(2)public DatagramPacket(byte ibuf[],int ilength,InetAddress

iaddr,int iport)

功能:创建一个用于发送数据报的DatagramPacket类对象。

参数:

ibuf:存储数据报的缓冲区。

ilength:发送数据报的长度,必须小于等于ibuf.length。

iaddr:数据报要发送到的目的IP地址。

iport:数据报要发送到的目的地址的端口号。

2.常用方法

(1)public synchronized InetAddress

getAddress()功能:返回存放在接收或发送的数据报中的IP址。

(2)public synchronized int

getPort()功能:返回存放在接收或发送的数据报中的端口号。

(3)public synchronized byte[] getData()功能:返回存放在数据报中的数据。

(4)public synchronized int getLength()功能:返回数据报中数据的长度。

(5)public synchronized void setAddress(InetAddress

iaddr)功能:设置发送数据报的目的地址为iaddr。

(6)public synchronized void setPort(int

iport)功能:设置发送数据报的目的地址的端口号为iport。

(7)public synchronized void setData(byte

ibuf[])功能:设置数据报中的数据内容为字节数组ibuf的数据。

(8)public synchronized void setLength(int

ilength)功能:设置数据报中的数据的长度为ilength。

2.2

DatagramSocket类

该类表示用来发送和接收数据报包的套接字(Socket)。要收发DatagramPacket,必须打开一个数据报套接字(Datagram

Socket)。在Java中,数据报套接字通过DatagramSocket类来创建和访问。

1.构造函数

(1)public DatagramSocket() throws SocketException

功能:创建用于数据报通信的socket对象,由本地主机自动指定的一个可用的端口号。

(2)public DatagramSocket(int port) throws SocketException

功能:创建用于数据报通信的socket对象,并且把它绑定到本地主机指定的端口port。

(3)public DatagramSocket(int port,InetAddress addr) throws

SocketException

功能:创建用于数据报通信的socket对象,并绑定到指定的本地地址addr的指定端口port。端口号port必须为0和65535之间的一个。

2.常用方法

(1)public void send(DatagramPacket p) throws

IOException功能:从此socket发送数据报包。

(2)public synchronized void receive(DatagramPacket p) throws

IOException功能:从网络接收一个UDP数据报包。存储在DatagramPacket类对象p中。该数据报包还包含发送方的IP

地址和发送方主机的端口号。

(3)public InetAddress

getLocalAddress()功能:获取该socket绑定的本地地址。

(4)public int getLocalPort()功能:获取该socket绑定的本地主机的端口号。

(5)public void close()功能:释放该数据报socket所占用的端口。

【例 1】

获取本地主机的时间,通过UDP实现。

(1)服务器端程序TimeServer_UDP.java

import

java.net.*;

import java.io.*;

import java.util.*;

public class TimeServer_UDP{

public static void main(String args[]) throws

IOException{

DatagramSocket socket = new

DatagramSocket(3000);//Socket对象.端口3000

System.out.println("等待接收数据......");

while(true){

byte buf[] =

new byte[256];

DatagramPacket

packet = new DatagramPacket(buf,buf.length);

socket.receive(packet);

String date =

new Date().toString();

buf =

date.getBytes();

InetAddress

addr = packet.getAddress();

int port =

packet.getPort();

packet = new

DatagramPacket(buf,buf.length,addr,port);

socket.send(packet);

System.out.println("已接收来自"

+ addr.toString() + ":"+port+"的数据");

}

}

}

(2)客户端程序TimeClient_UDP.java

import

java.net.*;

import java.io.*;

public class TimeClient_UDP{

public static void main(String args[]) throws

IOException{

String host =

"localhost";

byte msg[] = new

byte[256];//存放收发数据

InetAddress addr =

InetAddress.getByName(host);//获取主机地址

System.out.println("侦听主机为:"+addr);

DatagramPacket packet = new

DatagramPacket(msg,msg.length,addr,3000);//创建要收发的数据报

DatagramSocket socket = new

DatagramSocket();//创建用于通信的Socket对象

socket.send(packet);//发送数据报

packet = new

DatagramPacket(msg,msg.length);//创建接收的数据报

socket.receive(packet);//接收数据报,存放到packet中

String time = new

String(packet.getData());//获取数据报中的数据内容

System.out.println("侦听主机:"+host+"的当前日期为:"+time);

socket.close();//释放Socket

}

}

a4c26d1e5885305701be709a3d33442f.png服务器端

a4c26d1e5885305701be709a3d33442f.png客户端

3

基于UDP协议的Socket编程

 3.1基于UDP协议的Socket编程的基本步骤

开发基于UDP协议的网络应用程序时,需分别编写客户端和服务器端两个应用程序,这两个程序的基本架构相似。基本步骤如下:

(1)建立一个DatagramSocket对象;

(2)创建用于接收或发送数据的DatagramPacket对象;

(3)利用DatagramSocket类方法receive()或send()接收或发送数据报包。

3.2

应用举例

【例 2】

编写一个基于UDP协议的Socket网络点对点聊天程序,可实现客户端和服务器端信息的互发。

1.编写服务器端程序Serverapp_UDP.java

2.编写客户端程序Clientapp_UDP.java

1.服务器端程序具体开发步骤

(1)建立一个DatagramSocket对象;

(2)进入收发数据报包的循环,直到客户端数据传送完毕。循环过程如下:

 1)创建一个用于接收数据的DatagramPakcet对象;

 2)利用DatagramSocket类方法receive()等待接收客户端的数据报包;

 3)处理客户端数据报包内容;

 4)创建一个用于发送响应信息数据的DatagramPakcet对象;

5)利用DatagramSocket类方法send()向客户端发送包含响应信息的数据报包;

(3)客户端数据传送完毕,释放Socket。

import

java.awt.*;

import java.awt.event.*;

import java.io.*;

import java.net.*;

public class Serverapp_UDP extends WindowAdapter implements

ActionListener,KeyListener{

TextField str_send;

Label label;

TextArea msg;

Button send,exit;

Panel

p1; String hostname;

DatagramSocket

receiveSocket,sendSocket;

DatagramPacket

receivePacket,sendPacket; public void display(){

Frame f=new

Frame("在线聊天——服务器");

f.setSize(400,350);

f.setLocation(400,400);

f.setBackground(Color.green);

p1=new

Panel();

f.add(p1,"South");

msg=new

TextArea();

msg.setSize(100,250);

msg.setBackground(Color.white);

msg.setEditable(false);

f.add(msg);

label=new

Label("发送消息");

p1.add(label);

str_send=new

TextField(20);

p1.add(str_send);

str_send.addKeyListener(this);

send=new

Button("发送");

p1.add(send);

send.addActionListener(this);

exit=new

Button("退出");

p1.add(exit);

exit.addActionListener(this);

f.addWindowListener(this);

f.setVisible(true);

try{

sendSocket=new DatagramSocket(5000);

}catch(Exception e){

msg.append(e+"n");

} } //接受信息

public void

receiveMessage(){

try {

receiveSocket=new

DatagramSocket(3333);

while(true){

byte[]

buf=new byte[500];

receivePacket=new DatagramPacket(buf,buf.length);

receiveSocket.receive(receivePacket);

if(receivePacket.getLength()==0){

System.out.println("消息为空");

continue;

}

ByteArrayInputStream bin=new

ByteArrayInputStream(receivePacket.getData());

BufferedReader reader=new BufferedReader(new

InputStreamReader(bin));

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值