Java NIOインスタンス-DatagramChannelによるUDPプロトコル転送
13515 ワード
自分の学習ノート(後で問題が発見されたら修正する)
ネット上でudpプロトコルについていくつか見つけて、勉強した後に1つの例を書いて学習のために使います.
他の人の経験に基づいて、以下の内容をまとめました.
TCPとUDPの効率比較:
TCPプロトコルは、効率に対する要求が比較的低いが、正確性に対する要求が比較的高いシーン、または接続概念があるシーンに適用される.一方、UDPプロトコルは、効率に対する要求が比較的高く、正確性に対する要求が比較的低いシーンに適用されます.
TCPとUDP応用シーン:
TCPはネットワークデータベース、分布式高精度計算システムのデータ伝送に用いることができる.UDPはサービスシステムの内部間のデータ伝送に用いることができ、データが比較的多いため、内部システムのローカルエリアネットワーク内のパケット損失率が低く、パケット損失であっても、せいぜい操作が無効である場合、UDPはよく使用される.
インターネットで収集された資料:
TCPバイトフローとUDPデータレポート:http://network.51cto.com/art/201310/413326.htm
TCPとUDPの違い(回転):http://www.cnblogs.com/bizhu/archive/2012/05/12/2497493.html
JAva nio対OP_WRITEの処理はネットの速度の遅い接続を解決します:http://blog.sina.com.cn/s/blog_783ede0301013g5n.html
テストツール:
clumsyツールを使用すると、ネットワークのパケット損失、ネットワーク遅延などの劣悪な環境をシミュレートできます.
ダウンロード先:http://download.csdn.net/detail/foart/8999423
サービス側
クライアント
ネット上でudpプロトコルについていくつか見つけて、勉強した後に1つの例を書いて学習のために使います.
他の人の経験に基づいて、以下の内容をまとめました.
TCPとUDPの効率比較:
TCPプロトコルは、効率に対する要求が比較的低いが、正確性に対する要求が比較的高いシーン、または接続概念があるシーンに適用される.一方、UDPプロトコルは、効率に対する要求が比較的高く、正確性に対する要求が比較的低いシーンに適用されます.
TCPとUDP応用シーン:
TCPはネットワークデータベース、分布式高精度計算システムのデータ伝送に用いることができる.UDPはサービスシステムの内部間のデータ伝送に用いることができ、データが比較的多いため、内部システムのローカルエリアネットワーク内のパケット損失率が低く、パケット損失であっても、せいぜい操作が無効である場合、UDPはよく使用される.
インターネットで収集された資料:
TCPバイトフローとUDPデータレポート:http://network.51cto.com/art/201310/413326.htm
TCPとUDPの違い(回転):http://www.cnblogs.com/bizhu/archive/2012/05/12/2497493.html
JAva nio対OP_WRITEの処理はネットの速度の遅い接続を解決します:http://blog.sina.com.cn/s/blog_783ede0301013g5n.html
テストツール:
clumsyツールを使用すると、ネットワークのパケット損失、ネットワーク遅延などの劣悪な環境をシミュレートできます.
ダウンロード先:http://download.csdn.net/detail/foart/8999423
サービス側
package cn;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* @author
* @date 2015-8-7 11:36:25
*/
import java.nio.channels.*;
import java.nio.charset.*;
import java.net.*;
import java.io.*;
import java.util.*;
import java.nio.*;
public class DatagramChannelServerDemo {
// UDP
private int port = 9975;
DatagramChannel channel;
private Charset charset = Charset.forName("UTF-8");
private Selector selector = null;
public DatagramChannelServerDemo() throws IOException {
try {
selector = Selector.open();
channel = DatagramChannel.open();
} catch (Exception e) {
selector = null;
channel = null;
System.out.println(" ");
}
System.out.println(" ");
}
/* */
public ByteBuffer encode(String str) {
return charset.encode(str);
}
/* */
public String decode(ByteBuffer bb) {
return charset.decode(bb).toString();
}
/* */
public void service() throws IOException {
if(channel==null || selector==null) return;
channel.configureBlocking(false);
channel.socket().bind(new InetSocketAddress(port));
// channel.write(ByteBuffer.wrap(new String("aaaa").getBytes()));
channel.register(selector, SelectionKey.OP_READ);
/** , SelectionKey */
while (selector.select() > 0) {
System.out.println(" channel ");
/* SelectionKey */
Iterator iterator = selector.selectedKeys().iterator();
while (iterator.hasNext()) {
SelectionKey key = null;
try {
key = (SelectionKey) iterator.next();
iterator.remove();
if (key.isReadable()) {
reveice(key);
}
if (key.isWritable()) {
// send(key);
}
} catch (IOException e) {
e.printStackTrace();
try {
if (key != null) {
key.cancel();
key.channel().close();
}
} catch (ClosedChannelException cex) {
e.printStackTrace();
}
}
}
/* */
}
/* */
}
/*
* receive() IO
* connect(), <span style="font-family: Arial, Helvetica, sans-serif;">connect() </span><span style="font-family: Arial, Helvetica, sans-serif;"> read()\write() , java.nio.channels</span>
* .NotYetConnectedException connect() , read write.
*/
synchronized public void reveice(SelectionKey key) throws IOException {
if (key == null)
return;
// *** channel.receive() ***//
// :
DatagramChannel sc = (DatagramChannel) key.channel();
String content = "";
// create buffer with capacity of 48 bytes
ByteBuffer buf = ByteBuffer.allocate(1024);// java (utf-8) 3 ,gbk 2
buf.clear();
SocketAddress address = sc.receive(buf); // read into buffer.
String clientAddress = address.toString().replace("/", "").split(":")[0];
String clientPost = address.toString().replace("/", "").split(":")[1];
buf.flip(); // make buffer ready for read
while (buf.hasRemaining()) {
buf.get(new byte[buf.limit()]);// read 1 byte at a time
content += new String(buf.array());
}
buf.clear(); // make buffer ready for writing
System.out.println(" :" + content.trim());
// ;udp , ,
ByteBuffer buf2 = ByteBuffer.allocate(65507);
buf2.clear();
buf2
.put(" abc..UDP , , , 。 UDP , , , 。 UDP , , , 。 @Q"
.getBytes());
buf2.flip();
channel.send(buf2, new InetSocketAddress(clientAddress,Integer.parseInt(clientPost))); //
//
ByteBuffer buf3 = ByteBuffer.allocate(65507);
buf3.clear();
buf3.put(" ".getBytes());
buf3.flip();
channel.send(buf3, new InetSocketAddress(clientAddress, Integer.parseInt(clientPost))); //
}
int y = 0;
public void send(SelectionKey key) {
if (key == null)
return;
// ByteBuffer buff = (ByteBuffer) key.attachment();
DatagramChannel sc = (DatagramChannel) key.channel();
try {
sc.write(ByteBuffer.wrap(new String("aaaa").getBytes()));
} catch (IOException e1) {
e1.printStackTrace();
}
System.out.println("send2() " + (++y));
}
/* */
public void sendFile(SelectionKey key) {
if (key == null)
return;
ByteBuffer buff = (ByteBuffer) key.attachment();
SocketChannel sc = (SocketChannel) key.channel();
String data = decode(buff);
if (data.indexOf("get") == -1)
return;
String subStr = data.substring(data.indexOf(" "), data.length());
System.out.println(" " + subStr);
FileInputStream fileInput = null;
try {
fileInput = new FileInputStream(subStr);
FileChannel fileChannel = fileInput.getChannel();
fileChannel.transferTo(0, fileChannel.size(), sc);
fileChannel.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fileInput.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
public static void main(String[] args) throws IOException {
new DatagramChannelServerDemo().service();
}
}
クライアント
package cn;
import java.io.IOException;
import java.net.ConnectException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* @author
* @date 2015-8-7 11:36:25
*/
import java.nio.channels.*;
import java.nio.charset.*;
import java.net.*;
import java.io.*;
import java.util.*;
import java.nio.*;
public class DatagramChannelClientDemo {
// UDP
private String serverIp = "127.0.0.1";
private int port = 9975;
// private ServerSocketChannel serverSocketChannel;
DatagramChannel channel;
private Charset charset = Charset.forName("UTF-8");
private Selector selector = null;
public DatagramChannelClientDemo() throws IOException {
try {
selector = Selector.open();
channel = DatagramChannel.open();
} catch (Exception e) {
selector = null;
channel = null;
System.out.println(" ");
}
System.out.println(" ");
}
/* */
public ByteBuffer encode(String str) {
return charset.encode(str);
}
/* */
public String decode(ByteBuffer bb) {
return charset.decode(bb).toString();
}
/* */
public void service() throws IOException {
if(channel==null || selector==null) return;
channel.configureBlocking(false);
channel.connect(new InetSocketAddress(serverIp, port));//
channel.write(ByteBuffer.wrap(new String(" ").getBytes()));
channel.register(selector, SelectionKey.OP_READ);
/** , SelectionKey */
while (selector.select() > 0) {
/* SelectionKey */
Iterator iterator = selector.selectedKeys().iterator();
while (iterator.hasNext()) {
SelectionKey key = null;
try {
key = (SelectionKey) iterator.next();
iterator.remove();
if (key.isReadable()) {
reveice(key);
}
if (key.isWritable()) {
// send(key);
}
} catch (IOException e) {
e.printStackTrace();
try {
if (key != null) {
key.cancel();
key.channel().close();
}
} catch (ClosedChannelException cex) {
e.printStackTrace();
}
}
}
/* */
}
/* */
}
// /*
// * read() IO
// * */
// synchronized public void reveice2(SelectionKey key) throws IOException {
// if (key == null)
// return;
// // *** channel.read() ***//
// // :
// DatagramChannel sc = (DatagramChannel) key.channel();
// String content = "";
// // create buffer with capacity of 48 bytes
// ByteBuffer buf = ByteBuffer.allocate(3);// java (utf-8) 3 ,gbk 2
// int bytesRead = sc.read(buf); //read into buffer.
//
// while (bytesRead >0) {
// buf.flip(); //make buffer ready for read
// while(buf.hasRemaining()){
// buf.get(new byte[buf.limit()]); // read 1 byte at a time
// content += new String(buf.array());
// }
// buf.clear(); //make buffer ready for writing
// bytesRead = sc.read(buf);
// }
// System.out.println(" :" + content);
// }
/* */
synchronized public void reveice(SelectionKey key) throws IOException {
String threadName = Thread.currentThread().getName();
if (key == null)
return;
try {
// *** channel.receive() ***//
// :
DatagramChannel sc = (DatagramChannel) key.channel();
String content = "";
// ;udp , ,
ByteBuffer buf = ByteBuffer.allocate(65507);// java (utf-8) 3 ,gbk 2
buf.clear();
SocketAddress address = sc.receive(buf); // read into buffer.
String clientAddress = address.toString().replace("/", "").split(":")[0];
String clientPost = address.toString().replace("/", "").split(":")[1];
System.out.println(threadName + "\t" + address.toString());
buf.flip(); // make buffer ready for read
while (buf.hasRemaining()) {
buf.get(new byte[buf.limit()]);// read 1 byte at a time
byte[] tmp = buf.array();
content += new String(tmp);
}
buf.clear(); // make buffer ready for writing
System.out.println(threadName + " :" + content.trim());
//
content = "";
ByteBuffer buf2 = ByteBuffer.allocate(65507);// java (utf-8) 3 ,gbk 2
buf2.clear();
SocketAddress address2 = sc.receive(buf2); // read into buffer.
buf2.flip(); // make buffer ready for read
while (buf2.hasRemaining()) {
buf2.get(new byte[buf2.limit()]);// read 1 byte at a time
byte[] tmp = buf2.array();
content += new String(tmp);
}
buf2.clear(); // make buffer ready for writing
System.out.println(threadName + " 2:" + content.trim());
} catch (PortUnreachableException ex) {
System.out.println(threadName + " !");
}
send(2);
}
boolean flag = false;
public void send(int i) {
if (flag)
return;
try {
// channel.write(ByteBuffer.wrap(new String(" ( "+i+" )").getBytes()));
// channel.register(selector, SelectionKey.OP_READ );
ByteBuffer buf2 = ByteBuffer.allocate(48);
buf2.clear();
buf2.put((" ( " + i + " )").getBytes());
buf2.flip();
channel.write(buf2);
channel.register(selector, SelectionKey.OP_READ );
// int bytesSent = channel.send(buf2, new InetSocketAddress(serverIp,port)); //
} catch (IOException e) {
e.printStackTrace();
}
flag = true;
}
int y = 0;
public void send(SelectionKey key) {
if (key == null)
return;
// ByteBuffer buff = (ByteBuffer) key.attachment();
DatagramChannel sc = (DatagramChannel) key.channel();
try {
sc.write(ByteBuffer.wrap(new String("aaaa").getBytes()));
} catch (IOException e1) {
e1.printStackTrace();
}
System.out.println("send2() " + (++y));
}
/* */
public void sendFile(SelectionKey key) {
if (key == null)
return;
ByteBuffer buff = (ByteBuffer) key.attachment();
SocketChannel sc = (SocketChannel) key.channel();
String data = decode(buff);
if (data.indexOf("get") == -1)
return;
String subStr = data.substring(data.indexOf(" "), data.length());
System.out.println(" " + subStr);
FileInputStream fileInput = null;
try {
fileInput = new FileInputStream(subStr);
FileChannel fileChannel = fileInput.getChannel();
fileChannel.transferTo(0, fileChannel.size(), sc);
fileChannel.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fileInput.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
public static void main(String[] args) throws IOException {
new Thread(new Runnable() {
public void run() {
try {
new DatagramChannelClientDemo().service();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
// new Thread(new Runnable() {
// public void run() {
// try {
// new DatagramChannelClientDemo().service();
// } catch (IOException e) {
// e.printStackTrace();
// }
// }
// }).start();
}
}