问题描述
客户端可以给服务端发消息,服务端也可以给客户端反馈。注释最好清晰点,说明selector,channel,buffer的用法的实例。谢谢各位大牛,小弟刚学nio,c/s通信,希望给一个易懂的例子,谢谢大家。!:)
解决方案
解决方案二:
楼主OUT了,现在都用MINA了,apache上有现成的文档例子。
解决方案三:
呵呵,课程作业,不搞懂,咋考试呢。。
解决方案四:
服务器端代码为:29.30.packagehelloweenpad;31.32.importjava.io.FileInputStream;33.importjava.net.InetSocketAddress;34.importjava.net.Socket;35.importjava.nio.ByteBuffer;36.importjava.nio.CharBuffer;37.importjava.nio.channels.SelectionKey;38.importjava.nio.channels.Selector;39.importjava.nio.channels.ServerSocketChannel;40.importjava.nio.channels.SocketChannel;41.importjava.nio.charset.Charset;42.importjava.nio.charset.CharsetDecoder;43.importjava.nio.charset.CharsetEncoder;44.importjava.util.Iterator;45.importjava.util.Properties;46.47.publicclassMyFirstNIOServer{48.49.publicstaticfinalintPORT=12315;50.51.protectedSelectorselector;52.protectedCharsetcharset=Charset.forName("UTF-8");53.protectedCharsetEncodercharsetEncoder=charset.newEncoder();54.protectedCharsetDecodercharsetDecoder=charset.newDecoder();55.56.protectedPropertiestalks=newProperties();57.58.intclientCount;59.60.publicMyFirstNIOServer()throwsException{61.62.talks.load(newFileInputStream("E:\talk.properties"));63.64.selector=Selector.open();65.66.ServerSocketChannelserverSocketChannel=ServerSocketChannel.open();67.serverSocketChannel.socket().bind(newInetSocketAddress(PORT));//port68.serverSocketChannel.configureBlocking(false);69.serverSocketChannel.register(selector,SelectionKey.OP_ACCEPT);//register70.71.p("Serverlocalhost:"+PORT+"started.waitingforclients.");72.73.while(true){74.//selector线程。select()会阻塞,直到有客户端连接,或者有消息读入75.selector.select();76.Iterator<SelectionKey>iterator=selector.selectedKeys().iterator();77.while(iterator.hasNext()){78.79.SelectionKeyselectionKey=iterator.next();80.iterator.remove();//删除此消息81.82.//并在当前线程内处理。(为了高效,一般会在另一个线程中处理此消息,例如使用线程池等)83.handleSelectionKey(selectionKey);84.}85.}86.87.}88.89.publicvoidhandleSelectionKey(SelectionKeyselectionKey)throwsException{90.91.if(selectionKey.isAcceptable()){92.93.//有客户端进来94.clientCount++;95.96.ServerSocketChannelserverSocketChannel=(ServerSocketChannel)selectionKey.channel();97.SocketChannelsocketChannel=serverSocketChannel.accept();98.socketChannel.configureBlocking(false);99.Socketsocket=socketChannel.socket();100.101.//立即注册一个OP_READ的SelectionKey,接收客户端的消息102.SelectionKeykey=socketChannel.register(selector,SelectionKey.OP_READ);103.key.attach("第"+clientCount+"个客户端["+socket.getRemoteSocketAddress()+"]:");104.105.p(key.attachment()+"t[connected]=========================================");106.107.}elseif(selectionKey.isReadable()){108.109.//有消息进来110.111.ByteBufferbyteBuffer=ByteBuffer.allocate(100);112.SocketChannelsocketChannel=(SocketChannel)selectionKey.channel();113.114.try{115.intlen=socketChannel.read(byteBuffer);116.117.//如果len>0,表示有输入。如果len==0,表示输入结束。需要关闭socketChannel118.if(len>0){119.120.byteBuffer.flip();121.Stringmsg=charsetDecoder.decode(byteBuffer).toString();122.123.//根据客户端的消息,查找到对应的输出124.StringnewMsg=talks.getProperty(msg);125.if(newMsg==null)126.newMsg="Sorry?Idon'tunderstandyourmessage.";127.128.//UTF-8格式输出到客户端,并输出一个'n'129.130.socketChannel.write(charsetEncoder.encode(CharBuffer.wrap(newMsg+"n")));131.p(selectionKey.attachment()+"t[recieved]:"+msg+"----->t[send]:"+newMsg);132.133.}else{134.//输入结束,关闭socketChannel135.p(selectionKey.attachment()+"readfinished.closesocketChannel.");136.socketChannel.close();137.}138.139.}catch(Exceptione){140.141.//如果read抛出异常,表示连接异常中断,需要关闭socketChannel142.e.printStackTrace();143.144.p(selectionKey.attachment()+"socketclosed?");145.socketChannel.close();146.}147.148.}elseif(selectionKey.isWritable()){149.p(selectionKey.attachment()+"TODO:isWritable()????????????????????????????");150.}elseif(selectionKey.isConnectable()){151.p(selectionKey.attachment()+"TODO:isConnectable()?????????????????????????");152.}else{153.p(selectionKey.attachment()+"TODO:else.");154.}155.156.}157.158.publicstaticvoidp(Objectobject){159.System.out.println(object);160.}161.162.publicstaticvoidmain(String[]args)throwsException{163.newMyFirstNIOServer();164.}165.166.}//addby郄永军
解决方案五:
客户端:packagehelloweenpad;171.172.importjava.io.BufferedReader;173.importjava.io.FileInputStream;174.importjava.io.InputStream;175.importjava.io.InputStreamReader;176.importjava.io.OutputStream;177.importjava.net.Socket;178.importjava.util.Properties;179.importjava.util.Random;180.181.publicclassMyFirstNIOClientTestextendsThread{182.183.publicstaticfinalStringHOST="localhost";184.publicstaticfinalintPORT=12315;185.186.booleanexist=false;187.188.Propertiestalks=newProperties();189.Randomrandom=newRandom();190.String[]keys;191.192.intmessageCount=0;193.194.publicvoidrun(){195.196.try{197.198.//对话内容199.talks.load(newFileInputStream("E:\talk.properties"));200.201.//客户端发送"="左边的内容202.keys=newString[talks.size()];203.talks.keySet().toArray(keys);204.205.Socketsocket=newSocket(HOST,PORT);206.207.OutputStreamous=socket.getOutputStream();208.InputStreamins=socket.getInputStream();209.210.//接收线程,接收服务器的回应211.RecieverThreadreciever=newRecieverThread(ins);212.reciever.start();213.214.while(!exist){215.216.messageCount++;217.218.//选择一个随机消息219.Stringmsg=chooseMessage();220.221.synchronized(ins){222.223.//发送给服务器端224.ous.write(msg.getBytes("UTF-8"));225.226.System.out.println("[send]t"+messageCount+":"+msg);227.228.//然后等待接收线程229.ins.wait();230.}231.232.if(msg.equals("Bye")){233.break;234.}235.}236.237.ins.close();238.ous.close();239.socket.close();240.241.}catch(Exceptione){242.e.printStackTrace();243.}244.245.}246.247.publicStringchooseMessage(){248.249.intindex=random.nextInt(keys.length);250.Stringmsg=keys[index];251.252.//如果10次就选中Bye,则重新选择,为了使对话内容多一些253.if(messageCount<10&&msg.equalsIgnoreCase("Bye")){254.returnchooseMessage();255.}256.257.returnmsg;258.}259.260.//接收线程261.classRecieverThreadextendsThread{262.privateInputStreamins;263.264.publicRecieverThread(InputStreamins){265.this.ins=ins;266.}267.268.@Override269.publicvoidrun(){270.271.try{272.Stringline=null;273.274.BufferedReaderr=newBufferedReader(newInputStreamReader(275.ins,"UTF-8"));276.277.//readLine()会阻塞,直到服务器输出一个'n'278.while((line=r.readLine())!=null){279.280.System.out.println("[Recieved]:"+line);281.282.synchronized(ins){283.//接收到服务器的消息,通知下主线程284.ins.notify();285.}286.if(line.trim().equals("Bye")){287.exist=true;288.break;289.}290.}291.}catch(Exceptione){292.e.printStackTrace();293.}294.}295.296.}297.298.publicstaticvoidmain(String[]args)throwsException{299.300.//开三个客户端线程301.for(inti=0;i<3;i++){302.try{303.newMyFirstNIOClientTest().start();304.}catch(Exceptione){305.e.printStackTrace();306.}307.}308.309.}310.}//addby郄永军
解决方案六:
LS有魄力
解决方案七:
。。。。