æä¸å¦ä¹ äºä¸Java ç NIO Socketç¼ç¨ï¼åäºä¸é¢è¿ä¸ªå°ç¨åºï¼å æ¬æå¡å¨ç«¯ä¸å®¢æ·ç«¯ãå®ç°çåè½ä¸ºå®¢æ·ç«¯åæå¡å¨ç«¯åéé峿°ç®çæ¶æ¯ï¼æå¡å¨ç«¯ä¸æ¡ä¸æ¡çååºãæ¶æ¯å 容ä¿åå¨talks.propertiesæä»¶ä¸ï¼å 容为ï¼
Hi=Hi
Bye=Bye
åºåææå =çæ¯å°ä¸é
ä¸¾å¤´æææ=ä½å¤´ææ 乡
å°å°ç¦»å®¶è大å=乡鳿 æ¹é¬æ¯è¡°
天ççå°è=å®å¡éæ²³å¦
ææ¯ç²=ææ¯ä¹
ææ¯å®¢æ·ç«¯=ææ¯æå¡å¨
ææ¯å¨æé©°=ææ¯å¨æ¶¦å
客æ·ç«¯ä¼éå³åéâ=âå·¦è¾¹çæ¶æ¯ï¼æå¡å¨ç«¯ä¼ååºå®¢æ·ç«¯â=âå³è¾¹çæ¶æ¯ã妿客æ·ç«¯æ³æå¼è¿æ¥ï¼ä¼åæå¡å¨åéä¸ä¸ª"Bye"ï¼ç¶åæå¡å¨ä¼ååºä¸ä¸ª"Byeâãæ¶å°æå¡å¨ç«¯ç"Bye"åï¼å®¢æ·ç«¯ä¼æå¼è¿æ¥ã
å½ç¶ï¼javaçpropertiesæä»¶ä¸æ¥å䏿å 容ï¼ä½ éè¦native2asciiä¸ä¸ãtalks.properties çå®é æä»¶å 容为ï¼
Hi=Hi
Bye=Bye
\u5E8A\u524D\u660E\u6708\u5149=\u7591\u662F\u5730\u4E0A\u971C
\u4E3E\u5934\u671B\u660E\u6708=\u4F4E\u5934\u601D\u6545\u4E61
\u5C11\u5C0F\u79BB\u5BB6\u8001\u5927\u56DE=\u4E61\u97F3\u65E0\u6539\u9B13\u6BDB\u8870
\u5929\u738B\u76D6\u5730\u864E=\u5B9D\u5854\u9547\u6CB3\u5996
\u6211\u662F\u7532=\u6211\u662F\u4E59
\u6211\u662F\u5BA2\u6237\u7AEF=\u6211\u662F\u670D\u52A1\u5668
\u6211\u662F\u5468\u661F\u9A70=\u6211\u662F\u5468\u6DA6\u53D1
ç䏿å¡å¨ç«¯ç代ç ãæ¤ä¾ä¸çæå¡å¨ç«¯åªæä¸ä¸ªä¸»çº¿ç¨ï¼ç¨äºselectoræä½ï¼å¹¶å¤çå¤ä¸ªå®¢æ·ç«¯çæ¶æ¯ãå¨å¸¸è§çsocketç¼ç¨ä¸ï¼æ¯ä¸ªå®¢æ·ç«¯é½éè¦åç¬å¼ä¸ä¸ªçº¿ç¨ï¼æçæ¯è¾ä½ã代ç 为ï¼
package helloweenpad;
import java.io.FileInputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.util.Iterator;
import java.util.Properties;
public class MyFirstNIOServer {
public static final int PORT = 12315;
protected Selector selector;
protected Charset charset = Charset.forName("UTF-8");
protected CharsetEncoder charsetEncoder = charset.newEncoder();
protected CharsetDecoder charsetDecoder = charset.newDecoder();
protected Properties talks = new Properties();
int clientCount;
public MyFirstNIOServer() throws Exception {
talks.load(new FileInputStream("E:\\talk.properties"));
selector = Selector.open();
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.socket().bind(new InetSocketAddress(PORT)); // port
serverSocketChannel.configureBlocking(false);
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);// register
p("Server localhost:" + PORT + " started. waiting for clients. ");
while (true) {
// selector 线ç¨ãselect() ä¼é»å¡ï¼ç´å°æå®¢æ·ç«¯è¿æ¥ï¼æè ææ¶æ¯è¯»å ¥
selector.select();
Iterator iterator = selector.selectedKeys().iterator();
while (iterator.hasNext()) {
SelectionKey selectionKey = iterator.next();
iterator.remove(); // å 餿¤æ¶æ¯
// å¹¶å¨å½å线ç¨å å¤çã(为äºé«æï¼ä¸è¬ä¼å¨å¦ä¸ä¸ªçº¿ç¨ä¸å¤çæ¤æ¶æ¯ï¼ä¾å¦ä½¿ç¨çº¿ç¨æ± ç)
handleSelectionKey(selectionKey);
}
}
}
public void handleSelectionKey(SelectionKey selectionKey) throws Exception {
if (selectionKey.isAcceptable()) {
// æå®¢æ·ç«¯è¿æ¥
clientCount++;
ServerSocketChannel serverSocketChannel = (ServerSocketChannel) selectionKey.channel();
SocketChannel socketChannel = serverSocketChannel.accept();
socketChannel.configureBlocking(false);
Socket socket = socketChannel.socket();
// ç«å³æ³¨åä¸ä¸ª OP_READ çSelectionKey, æ¥æ¶å®¢æ·ç«¯çæ¶æ¯
SelectionKey key = socketChannel.register(selector, SelectionKey.OP_READ);
key.attach("第 " + clientCount + " 个客æ·ç«¯ [" + socket.getRemoteSocketAddress() + "]: ");
p(key.attachment() + "\t[connected] =========================================");
} else if (selectionKey.isReadable()) {
// ææ¶æ¯è¿æ¥
ByteBuffer byteBuffer = ByteBuffer.allocate(100);
SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
try {
int len = socketChannel.read(byteBuffer);
// 妿len>0ï¼è¡¨ç¤ºæè¾å ¥ã妿len==0, 表示è¾å ¥ç»æãéè¦å ³é socketChannel
if (len > 0) {
byteBuffer.flip();
String msg = charsetDecoder.decode(byteBuffer).toString();
// æ ¹æ®å®¢æ·ç«¯çæ¶æ¯ï¼æ¥æ¾å°å¯¹åºçè¾åº
String newMsg = talks.getProperty(msg);
if (newMsg == null)
newMsg = "Sorry? I don't understand your message. ";
// UTF-8 æ ¼å¼è¾åºå°å®¢æ·ç«¯ï¼å¹¶è¾åºä¸ä¸ª'n'
socketChannel.write(charsetEncoder.encode(CharBuffer.wrap(newMsg + "\n")));
p(selectionKey.attachment() + "\t[recieved]: " + msg + " ----->\t[send]: " + newMsg);
} else {
// è¾å ¥ç»æï¼å ³é socketChannel
p(selectionKey.attachment() + "read finished. close socketChannel. ");
socketChannel.close();
}
} catch (Exception e) {
// 妿readæåºå¼å¸¸ï¼è¡¨ç¤ºè¿æ¥å¼å¸¸ä¸æï¼éè¦å ³é socketChannel
e.printStackTrace();
p(selectionKey.attachment() + "socket closed? ");
socketChannel.close();
}
} else if (selectionKey.isWritable()) {
p(selectionKey.attachment() + "TODO: isWritable() ???????????????????????????? ");
} else if (selectionKey.isConnectable()) {
p(selectionKey.attachment() + "TODO: isConnectable() ????????????????????????? ");
} else {
p(selectionKey.attachment() + "TODO: else. ");
}
}
public static void p(Object object) {
System.out.println(object);
}
public static void main(String[] args) throws Exception {
new MyFirstNIOServer();
}
}
åçä¸å®¢æ·ç«¯ä»£ç ãè¿ä¸ªå®¢æ·ç«¯ä½¿ç¨äºå¸¸è§çsocketç¼ç¨ï¼æ²¡æä½¿ç¨NIOãæ¯å¦ä½¿ç¨NIO对å¦ä¸æ¹æ¯éæçï¼å¯¹æ¹çä¸è§ï¼ä¹ä¸å ³å¿ãæ 论使ç¨NIOè¿æ¯ä½¿ç¨å¸¸è§socketï¼ææé½æ¯ä¸æ ·çï¼åªæ¯NIOçæçè¦é«ä¸äºã代ç 为ï¼
package helloweenpad;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Properties;
import java.util.Random;
public class MyFirstNIOClientTest extends Thread {
public static final String HOST = "localhost";
public static final int PORT = 12315;
boolean exist = false;
Properties talks = new Properties();
Random random = new Random();
String[] keys;
int messageCount = 0;
public void run() {
try {
// 对è¯å 容
talks.load(new FileInputStream("E:\\talk.properties"));
// 客æ·ç«¯åé "=" 左边çå 容
keys = new String[talks.size()];
talks.keySet().toArray(keys);
Socket socket = new Socket(HOST, PORT);
OutputStream ous = socket.getOutputStream();
InputStream ins = socket.getInputStream();
// æ¥æ¶çº¿ç¨ï¼æ¥æ¶æå¡å¨çååº
RecieverThread reciever = new RecieverThread(ins);
reciever.start();
while (!exist) {
messageCount++;
// éæ©ä¸ä¸ªéæºæ¶æ¯
String msg = chooseMessage();
synchronized (ins) {
// åéç»æå¡å¨ç«¯
ous.write(msg.getBytes("UTF-8"));
System.out.println("[send]\t" + messageCount + ": " + msg);
// ç¶åçå¾ æ¥æ¶çº¿ç¨
ins.wait();
}
if (msg.equals("Bye")) {
break;
}
}
ins.close();
ous.close();
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public String chooseMessage() {
int index = random.nextInt(keys.length);
String msg = keys[index];
// 妿 10 次就éä¸ Byeï¼åéæ°éæ©ï¼ä¸ºäºä½¿å¯¹è¯å 容å¤ä¸äº
if (messageCount < 10 && msg.equalsIgnoreCase("Bye")) {
return chooseMessage();
}
return msg;
}
// æ¥æ¶çº¿ç¨
class RecieverThread extends Thread {
private InputStream ins;
public RecieverThread(InputStream ins) {
this.ins = ins;
}
@Override
public void run() {
try {
String line = null;
BufferedReader r = new BufferedReader(new InputStreamReader(
ins, "UTF-8"));
// readLine()ä¼é»å¡ï¼ç´å°æå¡å¨è¾åºä¸ä¸ª '\n'
while ((line = r.readLine()) != null) {
System.out.println("[Recieved]: " + line);
synchronized (ins) {
// æ¥æ¶å°æå¡å¨çæ¶æ¯ï¼éç¥ä¸ä¸»çº¿ç¨
ins.notify();
}
if (line.trim().equals("Bye")) {
exist = true;
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws Exception {
// å¼ä¸ä¸ªå®¢æ·ç«¯çº¿ç¨
for (int i = 0; i < 3; i++) {
try {
new MyFirstNIOClientTest().start();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
=============================================================================
æå¡å¨ç«¯çè¾åºï¼
Server localhost:12315 started. waiting for clients.
第 1 个客æ·ç«¯ [/127.0.0.1:1890]: [connected] =========================================
第 2 个客æ·ç«¯ [/127.0.0.1:1865]: [connected] =========================================
第 3 个客æ·ç«¯ [/127.0.0.1:1866]: [connected] =========================================
第 2 个客æ·ç«¯ [/127.0.0.1:1865]: [recieved]: åºåææå -----> [send]: çæ¯å°ä¸é
第 3 个客æ·ç«¯ [/127.0.0.1:1866]: [recieved]: ææ¯å¨æé©° -----> [send]: ææ¯å¨æ¶¦å
第 1 个客æ·ç«¯ [/127.0.0.1:1890]: [recieved]: å°å°ç¦»å®¶è大å -----> [send]: 乡鳿 æ¹é¬æ¯è¡°
第 1 个客æ·ç«¯ [/127.0.0.1:1890]: [recieved]: åºåææå -----> [send]: çæ¯å°ä¸é
第 1 个客æ·ç«¯ [/127.0.0.1:1890]: [recieved]: ææ¯å®¢æ·ç«¯ -----> [send]: ææ¯æå¡å¨
第 3 个客æ·ç«¯ [/127.0.0.1:1866]: [recieved]: ä¸¾å¤´æææ -----> [send]: ä½å¤´ææ 乡
第 3 个客æ·ç«¯ [/127.0.0.1:1866]: [recieved]: åºåææå -----> [send]: çæ¯å°ä¸é
第 2 个客æ·ç«¯ [/127.0.0.1:1865]: [recieved]: ä¸¾å¤´æææ -----> [send]: ä½å¤´ææ 乡
第 1 个客æ·ç«¯ [/127.0.0.1:1890]: [recieved]: ææ¯ç² -----> [send]: ææ¯ä¹
第 1 个客æ·ç«¯ [/127.0.0.1:1890]: [recieved]: ææ¯å¨æé©° -----> [send]: ææ¯å¨æ¶¦å
第 3 个客æ·ç«¯ [/127.0.0.1:1866]: [recieved]: ä¸¾å¤´æææ -----> [send]: ä½å¤´ææ 乡
第 2 个客æ·ç«¯ [/127.0.0.1:1865]: [recieved]: åºåææå -----> [send]: çæ¯å°ä¸é
第 1 个客æ·ç«¯ [/127.0.0.1:1890]: [recieved]: åºåææå -----> [send]: çæ¯å°ä¸é
第 3 个客æ·ç«¯ [/127.0.0.1:1866]: [recieved]: åºåææå -----> [send]: çæ¯å°ä¸é
第 2 个客æ·ç«¯ [/127.0.0.1:1865]: [recieved]: Hi -----> [send]: Hi
第 2 个客æ·ç«¯ [/127.0.0.1:1865]: [recieved]: ä¸¾å¤´æææ -----> [send]: ä½å¤´ææ 乡
第 2 个客æ·ç«¯ [/127.0.0.1:1865]: [recieved]: ä¸¾å¤´æææ -----> [send]: ä½å¤´ææ 乡
第 2 个客æ·ç«¯ [/127.0.0.1:1865]: [recieved]: å°å°ç¦»å®¶è大å -----> [send]: 乡鳿 æ¹é¬æ¯è¡°
第 3 个客æ·ç«¯ [/127.0.0.1:1866]: [recieved]: ææ¯ç² -----> [send]: ææ¯ä¹
第 2 个客æ·ç«¯ [/127.0.0.1:1865]: [recieved]: åºåææå -----> [send]: çæ¯å°ä¸é
第 1 个客æ·ç«¯ [/127.0.0.1:1890]: [recieved]: ææ¯å®¢æ·ç«¯ -----> [send]: ææ¯æå¡å¨
第 2 个客æ·ç«¯ [/127.0.0.1:1865]: [recieved]: Hi -----> [send]: Hi
第 3 个客æ·ç«¯ [/127.0.0.1:1866]: [recieved]: Hi -----> [send]: Hi
第 2 个客æ·ç«¯ [/127.0.0.1:1865]: [recieved]: ææ¯å¨æé©° -----> [send]: ææ¯å¨æ¶¦å
第 1 个客æ·ç«¯ [/127.0.0.1:1890]: [recieved]: ææ¯å¨æé©° -----> [send]: ææ¯å¨æ¶¦å
第 3 个客æ·ç«¯ [/127.0.0.1:1866]: [recieved]: ä¸¾å¤´æææ -----> [send]: ä½å¤´ææ 乡
第 2 个客æ·ç«¯ [/127.0.0.1:1865]: [recieved]: Bye -----> [send]: Bye
第 1 个客æ·ç«¯ [/127.0.0.1:1890]: [recieved]: Hi -----> [send]: Hi
第 2 个客æ·ç«¯ [/127.0.0.1:1865]: read finished. close socketChannel.
第 1 个客æ·ç«¯ [/127.0.0.1:1890]: [recieved]: Bye -----> [send]: Bye
第 3 个客æ·ç«¯ [/127.0.0.1:1866]: [recieved]: ææ¯å®¢æ·ç«¯ -----> [send]: ææ¯æå¡å¨
第 1 个客æ·ç«¯ [/127.0.0.1:1890]: read finished. close socketChannel.
第 3 个客æ·ç«¯ [/127.0.0.1:1866]: [recieved]: ææ¯å®¢æ·ç«¯ -----> [send]: ææ¯æå¡å¨
第 3 个客æ·ç«¯ [/127.0.0.1:1866]: [recieved]: Bye -----> [send]: Bye
第 3 个客æ·ç«¯ [/127.0.0.1:1866]: read finished. close socketChannel.
客æ·ç«¯çè¾åºï¼
[send] 1: ææ¯å¨æé©°
[send] 1: å°å°ç¦»å®¶è大å
[Recieved]: 乡鳿 æ¹é¬æ¯è¡°
[send] 2: åºåææå
[Recieved]: çæ¯å°ä¸é
[send] 3: ææ¯å®¢æ·ç«¯
[Recieved]: ææ¯æå¡å¨
[Recieved]: çæ¯å°ä¸é
[Recieved]: ææ¯å¨æ¶¦å
[Recieved]: ä½å¤´ææ 乡
[send] 2: ä¸¾å¤´æææ
[Recieved]: çæ¯å°ä¸é
[send] 3: åºåææå
[send] 1: åºåææå
[send] 2: ä¸¾å¤´æææ
[Recieved]: ä½å¤´ææ 乡
[Recieved]: ææ¯ä¹
[send] 4: ææ¯ç²
[Recieved]: ææ¯å¨æ¶¦å
[send] 5: ææ¯å¨æé©°
[send] 3: åºåææå
[send] 6: åºåææå
[send] 4: ä¸¾å¤´æææ
[Recieved]: ä½å¤´ææ 乡
[send] 5: åºåææå
[Recieved]: çæ¯å°ä¸é
[Recieved]: çæ¯å°ä¸é
[Recieved]: çæ¯å°ä¸é
[Recieved]: Hi
[send] 4: Hi
[Recieved]: ä½å¤´ææ 乡
[send] 5: ä¸¾å¤´æææ
[Recieved]: ä½å¤´ææ 乡
[Recieved]: ä½å¤´ææ 乡
[send] 6: ä¸¾å¤´æææ
[send] 7: å°å°ç¦»å®¶è大å
[s
2
é¡¶
1
踩
å享å°ï¼

2010-09-28 15:38
æµè§ 22236
è¯è®º
5 楼
iHelios
2012-11-29
æè¿å¼å§å¦ä¹ Java NIO Socketç¼ç¨ï¼æäºå°æ¹ä¸å¤ªæç½ï¼
1. å¼å§æä»¥ä¸ºServer端åClientç«¯å ±ç¨ä¸ä¸ªSelectorï¼åæ¥æè§ä¼¼ä¹ä¸æ¯å ±ç¨çå§ï¼è°è¦è¯»æåï¼å°±èªå·±å¾selectoréæ³¨åé®å¼ï¼å循ç¯å¤çèªå·±selectorä¸çäºä»¶ï¼ä¸ç¥é对ä¸å¯¹ï¼
2. Serverç«¯ï¼æ³¨åäºACCEPTå¯å¨
Client端注åäºCONNECTäºä»¶è¿Serverå¹¶write(data) (ä¸å¤ªæç½è¿éæè¿æ²¡æ³¨åWRITEäºä»¶æä¹å°±å¯ä»¥åäº)
Serverç¥éClientè¿ä¸ï¼å¹¶æ³¨åäºREADäºä»¶ï¼åå¾READé®å¼, remove READé®å¼,å¤çREADäºä»¶(å ³é®æ¯è¿é æææå·²ç»removeäºREADé®å¼äºï¼æå®¢æ·ç«¯æ§è¡åæä½å ³éåï¼æå¡å¨ç«¯è¿å¨å¾ªç¯å¤çisReadableäºä»¶,è¿æ¯æä¹åäºåï¼)
叿æ¨å¸®å¿è§£æï¼
4 楼
somatezyc
2011-02-16
ä¾åæ¯åçä¸éï¼ä½æ¯ä½ é£ä¸ªåæ¥åççæä¸å¤´é¾æ°´ãããã为ä»ä¹ä½ é£ä¸ªåæ¥å没起ä½ç¨ï¼è¦èµ·ä½ç¨äºä¸æ¯å°±éæ»äºä¹ãããä¸ä¸ªçå¾ å¤éï¼ä¸ä¸ªçå¾ éæ¾éãããããã
3 楼
fortianwei
2011-01-19
lost_alien åé
// å¹¶å¨å½å线ç¨å å¤çã(为äºé«æï¼ä¸è¬ä¼å¨å¦ä¸ä¸ªçº¿ç¨ä¸å¤çæ¤æ¶æ¯ï¼ä¾å¦ä½¿ç¨çº¿ç¨æ± ç)
handleSelectionKey(selectionKey);
å¨å¦ä¸ä¸ªçº¿ç¨ä¸å¤çæ¤æ¶æ¯ ï¼ é£è¿è·ä¸ç¨nioæå¥åºå«åãã
å¤çæ¶æ¯å¼çº¿ç¨åæ¥å客æ·ç«¯å¼çº¿ç¨åä¸åãä¼ ç»çç»å®¢æ·ç«¯å¼çé£äºçº¿ç¨ç±äºç»å¸¸é»å¡æä»¥æçä½ãè¿éæ¯è¦å¼çº¿ç¨å¤çæ¶æ¯ï¼è¿ä¸ªçº¿ç¨åä¸ç¨çå¾ ï¼ç´æ¥å·¥ä½äºï¼è·é»å¡æ²¾ä¸ä¸è¾¹çäºã
è¯è¯´è¿propertyæä»¶æççä¹å欢ããã
2 楼
lost_alien
2010-12-01
// å¹¶å¨å½å线ç¨å å¤çã(为äºé«æï¼ä¸è¬ä¼å¨å¦ä¸ä¸ªçº¿ç¨ä¸å¤çæ¤æ¶æ¯ï¼ä¾å¦ä½¿ç¨çº¿ç¨æ± ç)
handleSelectionKey(selectionKey);
å¨å¦ä¸ä¸ªçº¿ç¨ä¸å¤çæ¤æ¶æ¯ ï¼ é£è¿è·ä¸ç¨nioæå¥åºå«åãã
1 楼
yangguo
2010-09-28
å¥ä»¬çpropertyæä»¶æ¯è¾æç¹è²ã