java网络编程:DatagramSocket类

UDP协议是一种不可靠的网络协议,它在通讯实例的两端个建立一个Socket,但这两个Socket之间并没有虚拟链路,这两个Socket只是发送和接受数据报的对象。 包java.net中提供了两个类DatagramSocketDatagramPacket用来支持数据报通信,DatagramSocket用于在程序之间建立传送数据报的通信连接, DatagramPacket则用来表示一个数据报。 DatagramSocket的构造方法:

DatagramSocket();
DatagramSocket(int prot);
DatagramSocket(int port, InetAddress laddr);
其中,port指明socket所使用的端口号,如果未指明端口号,则把socket连接到本地主机上一个可用的端口。laddr指明一个可用的本地地址。给出端口号时要保证不发生端口冲突,否则会生成SocketException类例外。注意:上述的两个构造方法都声明抛弃非运行时例外SocketException,程序中必须进行处理,或者捕获、或者声明抛弃。 用数据报方式编写client/server程序时,无论在客户方还是服务方,首先都要建立一个DatagramSocket对象,用来接收或发送数据报,然后使用DatagramPacket类对象作为传输数据的载体。


Socket之UDP套接字

UDP套接字:UDP套接字的使用是通过DatagramPacket类和DatagramSocket类,客户端和服务器端都是用DatagramPacket类来接收数据,使用DatagramSocket类来发送数据。

UDP客户端:也是主要执行三个步骤。

1.创建DatagramSocket实例;

2.使用DatagramSocket类的send()和receive()方法发送和接收DatagramPacket实例;

3.最后使用DatagramSocket类的close()方法销毁该套接字。

下面是例子,它主要执行三个步骤,

1.向服务器发送信息;

2.在receive()方法上最多阻塞等待3秒钟,在超时前若没有收到响应,则重发请求(最多重发5次);

3.关闭客户端。

//UDPEchoClientTimeout.java

import java.net.DatagramSocket;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.io.IOException;
import java.io.InterruptedIOException;

public class UDPEchoClientTimeout {

	private static final int TIMEOUT = 3000;   // 设置超时为3秒
	private static final int MAXTRIES = 5;     // 最大重发次数5次
	
	public static void main(String[] args) throws IOException {
	
	    if ((args.length < 2) || (args.length > 3)) { // Test for correct # of args
	      throw new IllegalArgumentException("Parameter(s): <Server> <Word> [<Port>]");
	    }
	    InetAddress serverAddress = InetAddress.getByName(args[0]); // 服务器地址
	    // Convert the argument String to bytes using the default encoding
	    //发送的信息
	    byte[] bytesToSend = args[1].getBytes();
	
	    int servPort = (args.length == 3) ? Integer.parseInt(args[2]) : 7;
	
	    DatagramSocket socket = new DatagramSocket();
	
	    socket.setSoTimeout(TIMEOUT); // 设置阻塞时间
	
	    DatagramPacket sendPacket = new DatagramPacket(bytesToSend, // 相当于将发送的信息打包
	        bytesToSend.length, serverAddress, servPort);
	
	    DatagramPacket receivePacket =                              // 相当于空的接收包
	        new DatagramPacket(new byte[bytesToSend.length], bytesToSend.length);
	
	    int tries = 0;      // Packets may be lost, so we have to keep trying
	    boolean receivedResponse = false;
	    do {
	      socket.send(sendPacket);          // 发送信息
	      try {
	        socket.receive(receivePacket); // 接收信息
	
	        if (!receivePacket.getAddress().equals(serverAddress)) {// Check source
	          throw new IOException("Received packet from an unknown source");
	        }
	        receivedResponse = true;
	      } catch (InterruptedIOException e) { // 当receive不到信息或者receive时间超过3秒时,就向服务器重发请求
	        tries += 1;
	        System.out.println("Timed out, " + (MAXTRIES - tries) + " more tries...");
	      }
	    } while ((!receivedResponse) && (tries < MAXTRIES));
	
	    if (receivedResponse) {
	      System.out.println("Received: " + new String(receivePacket.getData()));
	    } else {
	      System.out.println("No response -- giving up.");
	    }
	    socket.close();
	}
}

例子只是简单的向指定的服务器发送信息,并将发送的信息由服务器返回给指定客户端。

UDP服务器端:典型的UDP服务器要执行三个步骤,

1.创建一个指定了本地端口的DatagramSocket实例;

2.使用DatagramSocket的receive()方法接收一个来自客户端的DatagramPacket实例,而这个DatagramPacket实例在客户端创建时就包含了客户端的地址,这样我们就知道回复信息要发送到哪里了;

3.使用DatagramSocket类的send()和receive()方法来发送和接收DatagramPacket实例。

下面是例子

//UDPEchoServer.java
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class UDPEchoServer {

	private static final int ECHOMAX = 255; // 发送或接收的信息最大字节数
	
	public static void main(String[] args) throws IOException {
	
	    if (args.length != 1) { // Test for correct argument list
	      throw new IllegalArgumentException("Parameter(s): <Port>");
	    }
	
	    int servPort = Integer.parseInt(args[0]);
	
	    DatagramSocket socket = new DatagramSocket(servPort);
	    DatagramPacket packet = new DatagramPacket(new byte[ECHOMAX], ECHOMAX);
	
	    while (true) { // 不断接收来自客户端的信息及作出相应的相应
	      socket.receive(packet); // Receive packet from client
	      System.out.println("Handling client at " + packet.getAddress().getHostAddress() + " on port " + packet.getPort());
	      socket.send(packet); // 将客户端发送来的信息返回给客户端
	      packet.setLength(ECHOMAX); 
		 // 重置packet的内部长度,因为处理了接收到的信息后,数据包的内部长度将被                                                       
		 //设置为刚处理过的信息的长度,而这个长度可能比缓冲区的原始长度还要短,
		 //如果不重置,而且接收到的新信息长于这个内部长度,则超出长度的部分将会被截断,所以这点必须注意到。
	    }
	    /* NOT REACHED */
	}
}

例子只是简单地将客户端发送过来的信息再回复给客户端,服务器端会不断地receive来自客户端的信息,如果receive不到任何客户端请求,则将会进入阻塞状态,直到receive到有客户端请求位置。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值