Java UDP数据报和Socket

两个核心类DatagramPacket 数据包、DatagramSocket 数据包Socket
接收数据包的构造函数
public DatagramPacket(byte buf[], int length)
发送数据包的构造函数,比接收的多了发送目标地址
public DatagramPacket(byte buf[], int length, InetAddress address, int port)

两个核心方法 DatagramSocket类
public void send(DatagramPacket p) throws IOException
public synchronized void receive(DatagramPacket p) throws IOException
都是void的,发送和接受到的数据被包装到DatagramPacket中。


一些有用的应用程序

//简单UDP客户端,发送空数据到服务器,打印接收信息
public class SimpleUDPClient {

private int bufferSize;
private DatagramSocket socket;
private DatagramPacket out;

public SimpleUDPClient(InetAddress host, int port, int bufferSize,
int timeout) throws SocketException {
out = new DatagramPacket(new byte[1], 1, host, port);
this.bufferSize = bufferSize;
socket = new DatagramSocket(0);
socket.connect(host, port);
socket.setSoTimeout(timeout);
}

public SimpleUDPClient(InetAddress host, int port) throws SocketException {
this(host, port, 8192, 300000);
}

public byte[] request() {
DatagramPacket in;
try {
socket.send(out);
in = new DatagramPacket(new byte[bufferSize], bufferSize);
socket.receive(in);
} catch (IOException e) {
throw new RuntimeException(e);
}
return in.getData();
}

public static void main(String[] args) {
InetAddress host = null;
int port = 0;
try {
port = Integer.parseInt(args[0]);
host = InetAddress.getByName(args[1]);
port = Integer.parseInt("13");
if (port < 1 || port > 65535)
throw new Exception("端口号不对");
} catch (Exception e) {
try {
host = InetAddress.getByName("localhost");
port = 13;
} catch (UnknownHostException e1) {
}
}
try {
SimpleUDPClient client = new SimpleUDPClient(host, port);
byte[] response = client.request();
String result;
try {
result = new String(response, "ASCII");
} catch (UnsupportedEncodingException e) {
result = new String(response, "8859_1");
}
System.out.println(result);
} catch (Exception e) {
e.printStackTrace();
}
}
}



//可重用的UDPServer,继承类根据接收信息发送返回结果,
//要实现public abstract void response(DatagramPacket request)方法
public abstract class BaseUDPServer extends Thread {

private int bufferSize;
protected DatagramSocket socket;

public BaseUDPServer(int bufferSize, int port) throws SocketException {
this.bufferSize = bufferSize;
socket = new DatagramSocket(port);
}

public BaseUDPServer(int port) throws SocketException {
this(8192, port);
}

public void run() {
byte[] buf = new byte[bufferSize];
while (true) {
DatagramPacket in = new DatagramPacket(buf, bufferSize);
try {
socket.receive(in);
this.response(in);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}

public abstract void response(DatagramPacket request);
}

//继承BaseUDPServer的,实现了daytime协议的server
public class DayTimeServer extends BaseUDPServer {

private static final int DEFAULT_PORT = 13;

public DayTimeServer() throws SocketException {
super(DEFAULT_PORT);
}

public void response(DatagramPacket request) {
try {
String date = new Date() + "\r\n";
byte[] data = date.getBytes("ASCII");
DatagramPacket response = new DatagramPacket(data, data.length,
request.getAddress(), request.getPort());
socket.send(response);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
}

public static void main(String[] args) {
try {
BaseUDPServer server = new DayTimeServer();
server.start();
} catch (SocketException e) {
throw new RuntimeException(e);
}
}
}


echo协议
基于TCP的echo客户端,可以发送一个消息,然后在同一个连接上等待响应。但是基于UDP的echo客户端不能保证发送的消息总能被收到。因此要异步地发送和接受数据。
public class UDPEchoServer extends UDPServer {

public final static int DEFAULT_PORT = 7;

public UDPEchoServer() throws SocketException {
super(DEFAULT_PORT);
}

public void respond(DatagramPacket packet) {
try {
DatagramPacket outgoing = new DatagramPacket(packet.getData(), packet.getLength(),
packet.getAddress(), packet.getPort());
socket.send(outgoing);
} catch (IOException ex) {
System.err.println(ex);
}
}

public static void main(String[] args) {
try {
UDPServer server = new UDPEchoServer();
server.start();
} catch (SocketException ex) {
System.err.println(ex);
}
}
}

public class UDPEchoClient {

private static final int DEFAULT_PORT = 7;

public static void main(String[] args) {
String hostname = "localhost";
int port = DEFAULT_PORT;
if (args.length > 0) {
hostname = args[0];
}
try {
DatagramSocket socket = new DatagramSocket();
InetAddress address = InetAddress.getByName(hostname);
socket.connect(address, port);
SenderThread sender = new SenderThread(socket, address, DEFAULT_PORT);
sender.start();
Thread receiver = new ReceiverThread(socket);
receiver.start();
} catch (SocketException e) {
throw new RuntimeException(e);
} catch (UnknownHostException e) {
throw new RuntimeException(e);
}
}
}

public class SenderThread extends Thread {

private DatagramSocket socket;
private InetAddress address;
private int port;
private boolean stopped = false;

public SenderThread(DatagramSocket socket, InetAddress address, int port) {
this.socket = socket;
this.address = address;
this.port = port;
}

public void halt() {
this.stopped = true;
}

public void run() {
Scanner sc = new Scanner(System.in);
while (true) {
if (stopped) return;
String input = sc.nextLine();
if (input.equals("."))
break;
byte[] in = input.getBytes();
DatagramPacket request = new DatagramPacket(in, in.length, address, port);
try {
socket.send(request);
} catch (IOException e) {
throw new RuntimeException(e);
}
Thread.yield();
}
}
}

public class ReceiverThread extends Thread {

private DatagramSocket socket;
private boolean stopped = false;

public void halt() {
this.stopped = true;
}

public ReceiverThread(DatagramSocket socket) {
this.socket = socket;
}

public void run() {
byte[] buffer = new byte[65507];
while (true) {
if (stopped) return;
DatagramPacket dp = new DatagramPacket(buffer, buffer.length);
try {
socket.receive(dp);
String s = new String(dp.getData(), 0, dp.getLength());
System.out.println(s);
Thread.yield();
} catch (IOException ex) {
System.err.println(ex);
}
}
}
}

public abstract class UDPServer extends Thread {

private int bufferSize; // in bytes
protected DatagramSocket socket;

public UDPServer(int port, int bufferSize) throws SocketException {
this.bufferSize = bufferSize;
this.socket = new DatagramSocket(port);
}

public UDPServer(int port) throws SocketException {
this(port, 8192);
}

public void run() {
byte[] buffer = new byte[bufferSize];
while (true) {
DatagramPacket incoming = new DatagramPacket(buffer, buffer.length);
try {
socket.receive(incoming);
this.respond(incoming);
} catch (IOException ex) {
System.err.println(ex);
}
} // end while
} // end run

public abstract void respond(DatagramPacket request);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值