├── .classpath ├── .gitignore ├── .project ├── .settings ├── org.eclipse.core.resources.prefs ├── org.eclipse.jdt.core.prefs └── org.maven.ide.eclipse.prefs ├── README.md ├── pom.xml ├── readme.txt ├── src ├── main │ └── java │ │ ├── com │ │ └── a2 │ │ │ └── nsocket │ │ │ ├── core │ │ │ ├── handler │ │ │ │ ├── IoHandler.java │ │ │ │ └── IoHandlerAdapter.java │ │ │ ├── polling │ │ │ │ ├── NioSocketAcceptorPoll.java │ │ │ │ └── NioSocketConnectorPoll.java │ │ │ ├── service │ │ │ │ ├── AbstractIoAcceptor.java │ │ │ │ ├── AbstractIoCommunicate.java │ │ │ │ ├── AbstractIoConnector.java │ │ │ │ ├── IoAcceptor.java │ │ │ │ ├── IoCommunicate.java │ │ │ │ └── IoConnector.java │ │ │ └── session │ │ │ │ ├── AbstractIoSession.java │ │ │ │ ├── IoSession.java │ │ │ │ ├── NioAcceptorSession.java │ │ │ │ ├── NioConnectorSession.java │ │ │ │ └── SocketSession.java │ │ │ ├── nSocket.java │ │ │ └── transport │ │ │ └── socket │ │ │ ├── SocketAcceptor.java │ │ │ ├── SocketConnector.java │ │ │ └── nio │ │ │ ├── AioSocketAcceptor.java │ │ │ ├── NioSocketAcceptor.java │ │ │ └── NioSocketConnector.java │ │ └── log4j.properties └── test │ └── java │ └── com │ └── a2 │ └── nsocket │ ├── AppTest.java │ ├── TestIoAcceptor.java │ └── TestIoConnector.java └── target └── classes └── log4j.properties /.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | 3 | # Package Files # 4 | *.jar 5 | *.war 6 | *.ear 7 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | nSocket 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.maven.ide.eclipse.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.maven.ide.eclipse.maven2Nature 22 | 23 | 24 | -------------------------------------------------------------------------------- /.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding/=UTF-8 3 | -------------------------------------------------------------------------------- /.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 3 | org.eclipse.jdt.core.compiler.compliance=1.5 4 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 5 | org.eclipse.jdt.core.compiler.source=1.5 6 | -------------------------------------------------------------------------------- /.settings/org.maven.ide.eclipse.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | fullBuildGoals=process-test-resources 4 | resolveWorkspaceProjects=true 5 | resourceFilterGoals=process-resources resources\:testResources 6 | skipCompilerPlugin=true 7 | version=1 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | nSocket 2 |
3 | nSocket Version 0.1 4 |
5 | =======
6 | nSocket is a high performance Lightweight Network Framework which is based on JAVA NIO.1 7 | and java NIO.2. Building this project is for easier coding network programs,the difference 8 | between nSocket and Mina or Netty is that nSocket will use NIO.2 to build asynchronous 9 | communication, further more, on the final edition of nSocket, the pattern of architecture 10 | will be based on P2P module.
11 | 12 | already implementation:
13 | 1、IoCommunicate--IoAcceptor--IoConnector
14 | 2、IoSession
15 | 3、IoHandler
16 | 4、A Simple Polling
17 |
18 | The Chinese introduction of nSocket is published on OSChina, you can click 19 | here
20 | Thanks for sharing and fork nSocket. 21 | 22 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | com.a2 6 | nSocket 7 | 0.0.1-SNAPSHOT 8 | jar 9 | 10 | nSocket 11 | http://maven.apache.org 12 | 13 | 14 | UTF-8 15 | 16 | 17 | 18 | 19 | junit 20 | junit 21 | 3.8.1 22 | test 23 | 24 | 25 | org.slf4j 26 | slf4j-api 27 | 1.7.2 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /readme.txt: -------------------------------------------------------------------------------- 1 | acceptor send method todo -------------------------------------------------------------------------------- /src/main/java/com/a2/nsocket/core/handler/IoHandler.java: -------------------------------------------------------------------------------- 1 | package com.a2.nsocket.core.handler; 2 | 3 | import com.a2.nsocket.core.session.IoSession; 4 | 5 | /** 6 | * IoHandler provide the interface for user to do detail implements 7 | * @author ChenHui 8 | * 9 | */ 10 | public interface IoHandler { 11 | 12 | /**while doing the init in socket --binding*/ 13 | void sessionOpening() throws Exception; 14 | 15 | void sessionClosed() throws Exception; 16 | 17 | /**when accept or connect */ 18 | void sessionOpened(IoSession session) throws Exception; 19 | 20 | /**when message receives*/ 21 | void messageReceive(IoSession session, Object message) throws Exception; 22 | /**when message send, actually its the time before sending the msg*/ 23 | void messageSend(IoSession session, Object message) throws Exception; 24 | 25 | void execptionCaught(IoSession session, Throwable cause); 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/a2/nsocket/core/handler/IoHandlerAdapter.java: -------------------------------------------------------------------------------- 1 | package com.a2.nsocket.core.handler; 2 | 3 | import com.a2.nsocket.core.session.IoSession; 4 | 5 | public class IoHandlerAdapter implements IoHandler{ 6 | 7 | public void sessionClosed() throws Exception { 8 | // TODO Auto-generated method stub 9 | 10 | } 11 | 12 | public void messageReceive(IoSession session, Object message) 13 | throws Exception { 14 | // TODO Auto-generated method stub 15 | 16 | } 17 | 18 | public void messageSend(IoSession session, Object message) throws Exception { 19 | // TODO Auto-generated method stub 20 | 21 | } 22 | 23 | public void execptionCaught(IoSession session, Throwable cause){ 24 | // TODO Auto-generated method stub 25 | 26 | } 27 | 28 | public void sessionOpening() throws Exception { 29 | // TODO Auto-generated method stub 30 | 31 | } 32 | 33 | public void sessionOpened(IoSession session) throws Exception { 34 | // TODO Auto-generated method stub 35 | 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/a2/nsocket/core/polling/NioSocketAcceptorPoll.java: -------------------------------------------------------------------------------- 1 | package com.a2.nsocket.core.polling; 2 | 3 | import java.nio.ByteBuffer; 4 | import java.nio.channels.SelectionKey; 5 | import java.nio.channels.Selector; 6 | import java.nio.channels.SocketChannel; 7 | import java.util.Iterator; 8 | 9 | import com.a2.nsocket.core.handler.IoHandler; 10 | import com.a2.nsocket.core.session.IoSession; 11 | import com.a2.nsocket.core.session.NioAcceptorSession; 12 | 13 | public class NioSocketAcceptorPoll implements Runnable { 14 | 15 | private IoHandler handler; 16 | private NioAcceptorSession session; 17 | private Selector selector; 18 | 19 | public NioSocketAcceptorPoll(IoHandler handler, IoSession session, Selector selector) { 20 | this.handler = handler; 21 | this.session = (NioAcceptorSession) session; 22 | this.selector = selector; 23 | } 24 | 25 | public void run() { 26 | try { 27 | while (true) { 28 | int n = selector.select(); 29 | if (n == 0) { 30 | continue; 31 | } 32 | Iterator iter = selector.selectedKeys() 33 | .iterator(); 34 | 35 | while (iter.hasNext()) { 36 | SelectionKey key = iter.next(); 37 | 38 | if (!key.isValid()) { 39 | continue; 40 | } else if (key.isAcceptable()) { 41 | acceptOperation(key); 42 | } else if (key.isReadable()) { 43 | readOperation(key); 44 | } else if (key.isWritable()) { 45 | //TODO 46 | } 47 | iter.remove(); 48 | } 49 | } 50 | } catch (Exception e) { 51 | e.printStackTrace(); 52 | handler.execptionCaught(session, e); 53 | } 54 | } 55 | 56 | private void readOperation(SelectionKey key) throws Exception { 57 | session.setSelecotr(selector); 58 | session.setKey(key); 59 | session.setIsServerChannel(false); 60 | 61 | SocketChannel channel = (SocketChannel) key.channel(); 62 | ByteBuffer dst = ByteBuffer.allocate(1024); 63 | int n = -1; 64 | try { 65 | n = channel.read(dst); 66 | } catch (Exception e) { 67 | System.err.println("cannot read io"); 68 | } 69 | if (n == -1) { 70 | key.cancel(); 71 | channel.close(); 72 | return; 73 | } 74 | dst.flip(); 75 | 76 | handler.messageReceive(session, dst); 77 | } 78 | 79 | private void acceptOperation(SelectionKey key) throws Exception { 80 | session.setSelecotr(selector); 81 | session.setKey(key); 82 | session.setIsServerChannel(true); 83 | handler.sessionOpened(session); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/main/java/com/a2/nsocket/core/polling/NioSocketConnectorPoll.java: -------------------------------------------------------------------------------- 1 | package com.a2.nsocket.core.polling; 2 | 3 | import java.io.IOException; 4 | import java.nio.ByteBuffer; 5 | import java.nio.channels.SelectionKey; 6 | import java.nio.channels.Selector; 7 | import java.nio.channels.SocketChannel; 8 | import java.util.Collection; 9 | import java.util.Iterator; 10 | import java.util.concurrent.atomic.AtomicInteger; 11 | 12 | import com.a2.nsocket.core.handler.IoHandler; 13 | import com.a2.nsocket.core.session.IoSession; 14 | import com.a2.nsocket.core.session.NioConnectorSession; 15 | 16 | public class NioSocketConnectorPoll implements Runnable { 17 | 18 | private IoHandler handler; 19 | private NioConnectorSession session; 20 | private Selector selector; 21 | private Collection keys; 22 | private AtomicInteger count = new AtomicInteger(0); 23 | 24 | public NioSocketConnectorPoll(IoHandler handler, IoSession session, 25 | Selector selector) { 26 | this.handler = handler; 27 | this.session = (NioConnectorSession) session; 28 | this.selector = selector; 29 | } 30 | 31 | public void run() { 32 | try { 33 | while (true) { 34 | int n = selector.select(); 35 | if (n == 0) { 36 | continue; 37 | } 38 | keys = selector.selectedKeys(); 39 | Iterator iter = keys.iterator(); 40 | 41 | while (iter.hasNext()) { 42 | SelectionKey key = iter.next(); 43 | iter.remove(); 44 | if (key.isValid()) { 45 | /**config*/ 46 | if (count.compareAndSet(0, 1)) { 47 | validOperation(key); 48 | } 49 | if (key.isReadable()) { 50 | readOperation(key); 51 | }else if(key.isWritable()){ 52 | 53 | } 54 | } 55 | } 56 | 57 | } 58 | } catch (Exception e) { 59 | e.printStackTrace(); 60 | } 61 | } 62 | 63 | private void validOperation(SelectionKey key) throws Exception { 64 | session.setSelecotr(selector); 65 | session.setKey(key); 66 | handler.sessionOpened(session); 67 | } 68 | 69 | private void readOperation(SelectionKey key) throws Exception { 70 | session.setSelecotr(selector); 71 | session.setKey(key); 72 | SocketChannel channel = (SocketChannel) key.channel(); 73 | int n = -1; 74 | ByteBuffer dst = ByteBuffer.allocate(1024); 75 | try { 76 | n = channel.read(dst); 77 | } catch (Exception e) { 78 | System.err.println("client read error"); 79 | } 80 | if (n == -1) { 81 | key.cancel(); 82 | channel.close(); 83 | return; 84 | } 85 | dst.flip(); 86 | 87 | handler.messageReceive(session, dst); 88 | } 89 | 90 | /** this should be considered */ 91 | public SocketChannelIterator getSocketChannelIter() { 92 | if (keys == null) { 93 | throw new IllegalStateException("the key is null"); 94 | } 95 | return new SocketChannelIterator(keys); 96 | } 97 | 98 | private static class SocketChannelIterator implements 99 | Iterator { 100 | 101 | private final Iterator iterator; 102 | 103 | private SocketChannelIterator(Collection keys) { 104 | iterator = keys.iterator(); 105 | } 106 | 107 | public boolean hasNext() { 108 | 109 | return iterator.hasNext(); 110 | } 111 | 112 | public SocketChannel next() { 113 | SelectionKey key = iterator.next(); 114 | if (key.isValid()) { 115 | return (SocketChannel) key.channel(); 116 | } 117 | return null; 118 | } 119 | 120 | public void remove() { 121 | iterator.remove(); 122 | } 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /src/main/java/com/a2/nsocket/core/service/AbstractIoAcceptor.java: -------------------------------------------------------------------------------- 1 | package com.a2.nsocket.core.service; 2 | 3 | import java.net.SocketAddress; 4 | import java.util.HashSet; 5 | import java.util.Set; 6 | 7 | import com.a2.nsocket.core.session.IoSession; 8 | 9 | public abstract class AbstractIoAcceptor extends AbstractIoCommunicate 10 | implements IoAcceptor { 11 | 12 | /** return io session form niosocketacceptor */ 13 | // private IoSession session; 14 | 15 | private Set tmpBindAddresses = new HashSet(); 16 | 17 | protected AbstractIoAcceptor() { 18 | super(); 19 | } 20 | 21 | public IoSession bind() { 22 | 23 | Set defaultLocalAddresses=new HashSet(); 24 | defaultLocalAddresses.addAll(getLocalAddresses()); 25 | tmpBindAddresses.addAll(defaultLocalAddresses); 26 | 27 | return bind0(defaultLocalAddresses); 28 | } 29 | 30 | public IoSession bind(SocketAddress localAddress) { 31 | if (localAddress == null) { 32 | throw new IllegalArgumentException("use bind() when params is null"); 33 | } 34 | Set addresses = new HashSet(); 35 | addresses.add(localAddress); 36 | tmpBindAddresses.addAll(addresses); 37 | return bind0(addresses); 38 | } 39 | 40 | public IoSession bind(Set localAddresses) { 41 | if (localAddresses.isEmpty()) { 42 | throw new IllegalArgumentException("use bind()"); 43 | } 44 | Set addresses = new HashSet(); 45 | addresses.addAll(localAddresses); 46 | tmpBindAddresses.addAll(addresses); 47 | return bind0(addresses); 48 | } 49 | 50 | /** bind0 implements by its sub class */ 51 | protected abstract IoSession bind0(Set localAddresses); 52 | 53 | public void unbind() { 54 | // TODO Auto-generated method stub 55 | } 56 | 57 | public void unbind(SocketAddress localAddress) { 58 | // TODO Auto-generated method stub 59 | 60 | } 61 | 62 | public void unbind(Set localAddresses) { 63 | // TODO Auto-generated method stub 64 | 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/com/a2/nsocket/core/service/AbstractIoCommunicate.java: -------------------------------------------------------------------------------- 1 | package com.a2.nsocket.core.service; 2 | 3 | import java.net.SocketAddress; 4 | import java.util.HashSet; 5 | import java.util.Set; 6 | 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | 10 | import com.a2.nsocket.core.handler.IoHandler; 11 | 12 | public abstract class AbstractIoCommunicate implements IoCommunicate { 13 | 14 | private final static Logger LOGGER = LoggerFactory 15 | .getLogger(AbstractIoCommunicate.class); 16 | 17 | private final Set localAddresses = new HashSet(); 18 | 19 | private Object addressLock = new Object(); 20 | 21 | // TODO 22 | protected AbstractIoCommunicate() { 23 | super(); 24 | } 25 | 26 | public final void setLocalAddress(SocketAddress localAddress) { 27 | setLocalAdderesses(localAddress); 28 | } 29 | 30 | public final void setLocalAdderesses(SocketAddress... localAddresses) { 31 | 32 | if (localAddresses == null) { 33 | throw new IllegalArgumentException("local addresses"); 34 | } 35 | 36 | synchronized (addressLock) { 37 | synchronized (this.localAddresses) { 38 | for (SocketAddress address : localAddresses) { 39 | this.localAddresses.add(address); 40 | } 41 | } 42 | } 43 | LOGGER.info("set local addresses successful"); 44 | } 45 | 46 | public final SocketAddress getLocalAddress() { 47 | if (localAddresses.isEmpty()) { 48 | return null; 49 | } 50 | return localAddresses.iterator().next(); 51 | } 52 | 53 | public final Set getLocalAddresses() { 54 | if (this.localAddresses.isEmpty()) { 55 | throw new IllegalArgumentException("set local address first"); 56 | } 57 | return this.localAddresses; 58 | } 59 | 60 | public abstract void setHandler(IoHandler handler); 61 | 62 | 63 | public abstract IoHandler getHandler(); 64 | 65 | 66 | public abstract void init() throws Exception; 67 | 68 | 69 | /** rely on its sub classes */ 70 | public abstract boolean isBlocakingChannel(); 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/com/a2/nsocket/core/service/AbstractIoConnector.java: -------------------------------------------------------------------------------- 1 | package com.a2.nsocket.core.service; 2 | 3 | import java.io.IOException; 4 | import java.net.InetSocketAddress; 5 | import java.net.SocketAddress; 6 | 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | 10 | import com.a2.nsocket.core.session.IoSession; 11 | 12 | public abstract class AbstractIoConnector extends AbstractIoCommunicate 13 | implements IoConnector { 14 | 15 | private static final Logger LOGGER = LoggerFactory 16 | .getLogger(AbstractIoConnector.class); 17 | 18 | private SocketAddress remoteAddress; 19 | 20 | public final IoSession connect(SocketAddress remoteAddress) throws IOException{ 21 | if (remoteAddress == null) { 22 | throw new IllegalArgumentException("remote address cannot be null"); 23 | } 24 | this.remoteAddress = remoteAddress; 25 | return connect0(this.remoteAddress); 26 | } 27 | 28 | public final IoSession connect(String HOST, int PORT) throws IOException{ 29 | if (HOST == null) { 30 | HOST = "127.0.0.1"; 31 | LOGGER.info("the remote address is 127.0.0.1 the HOST is null"); 32 | } 33 | if (PORT <= 0 || PORT >= 65535) { 34 | throw new IllegalArgumentException( 35 | "the PORT should between 1~65535"); 36 | } 37 | remoteAddress = new InetSocketAddress(HOST, PORT); 38 | return connect(remoteAddress); 39 | } 40 | 41 | /** the detail implements by its sub class 42 | * @throws Exception */ 43 | protected abstract IoSession connect0(SocketAddress remoteAddress) throws IOException; 44 | 45 | public void dispose() throws IOException{ 46 | dispose0(); 47 | } 48 | 49 | protected abstract void dispose0() throws IOException; 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/a2/nsocket/core/service/IoAcceptor.java: -------------------------------------------------------------------------------- 1 | package com.a2.nsocket.core.service; 2 | 3 | import java.net.SocketAddress; 4 | import java.util.Set; 5 | 6 | import com.a2.nsocket.core.session.IoSession; 7 | 8 | /** 9 | * interface for server socket 10 | * @author ChenHui 11 | * 12 | */ 13 | public interface IoAcceptor extends IoCommunicate{ 14 | 15 | IoSession bind(); 16 | 17 | IoSession bind(SocketAddress localAddress); 18 | 19 | IoSession bind(Set localAddresses); 20 | 21 | void unbind(); 22 | 23 | void unbind(SocketAddress localAddress); 24 | 25 | void unbind(Set localAddresses); 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/a2/nsocket/core/service/IoCommunicate.java: -------------------------------------------------------------------------------- 1 | package com.a2.nsocket.core.service; 2 | 3 | import java.net.SocketAddress; 4 | import java.util.Set; 5 | 6 | import com.a2.nsocket.core.handler.IoHandler; 7 | 8 | /** 9 | * the super interface for IoConnector and IoAcceptor 10 | * 11 | * @author ChenHui 12 | * 13 | */ 14 | public interface IoCommunicate { 15 | 16 | void setLocalAddress(SocketAddress localAddress); 17 | 18 | void setLocalAdderesses(SocketAddress... localAddresses); 19 | 20 | SocketAddress getLocalAddress(); 21 | 22 | Set getLocalAddresses(); 23 | 24 | void setHandler(IoHandler handler); 25 | 26 | /** get handler related to this communication */ 27 | IoHandler getHandler(); 28 | 29 | /** return the blocking type */ 30 | boolean isBlocakingChannel(); 31 | 32 | /**create open session operation*/ 33 | void init() throws Exception; 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/com/a2/nsocket/core/service/IoConnector.java: -------------------------------------------------------------------------------- 1 | package com.a2.nsocket.core.service; 2 | 3 | import java.io.IOException; 4 | import java.net.SocketAddress; 5 | 6 | import com.a2.nsocket.core.session.IoSession; 7 | 8 | public interface IoConnector extends IoCommunicate{ 9 | 10 | IoSession connect(SocketAddress remoteAddress) throws IOException; 11 | 12 | IoSession connect(String HOST,int PORT) throws IOException; 13 | 14 | /**dispose the link if there is only one link 15 | * @throws IOException */ 16 | void dispose() throws IOException; 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/a2/nsocket/core/session/AbstractIoSession.java: -------------------------------------------------------------------------------- 1 | package com.a2.nsocket.core.session; 2 | 3 | import java.io.IOException; 4 | import java.nio.ByteBuffer; 5 | import java.nio.channels.SelectionKey; 6 | import java.nio.channels.Selector; 7 | import java.nio.channels.ServerSocketChannel; 8 | import java.nio.channels.SocketChannel; 9 | 10 | import com.a2.nsocket.core.handler.IoHandler; 11 | 12 | public abstract class AbstractIoSession implements IoSession{ 13 | 14 | protected SelectionKey key; 15 | protected Selector selector; 16 | protected volatile boolean isServerChannel = false; 17 | 18 | public IoHandler getHandler() { 19 | // TODO Auto-generated method stub 20 | return null; 21 | } 22 | 23 | public void write(Object message) throws IOException { 24 | if (this.key == null) { 25 | throw new IllegalArgumentException("key is null"); 26 | } 27 | if (isServerChannel) { 28 | writeToServerChannel(this.key, message); 29 | } else { 30 | writeToCommonChannel(this.key,message); 31 | } 32 | 33 | } 34 | 35 | public void broadcast(Object message) { 36 | // TODO Auto-generated method stub 37 | 38 | } 39 | 40 | public Object read() { 41 | 42 | return null; 43 | } 44 | 45 | private void writeToServerChannel(SelectionKey key, Object message) 46 | throws IOException { 47 | ServerSocketChannel channel = (ServerSocketChannel) key.channel(); 48 | SocketChannel client = channel.accept(); 49 | client.configureBlocking(false); 50 | client.register(selector, SelectionKey.OP_READ); 51 | System.out.println("get" + client); 52 | ByteBuffer dst = ByteBuffer.allocate(1024); 53 | dst.put(message.toString().getBytes()); 54 | dst.flip(); 55 | client.write(dst); 56 | } 57 | 58 | /***/ 59 | private void writeToCommonChannel(SelectionKey key, Object message) 60 | throws IOException { 61 | SocketChannel client = (SocketChannel) key.channel(); 62 | client.configureBlocking(false); 63 | client.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE); 64 | ByteBuffer dst = ByteBuffer.allocate(1024); 65 | dst.put(message.toString().getBytes()); 66 | dst.flip(); 67 | client.write(dst); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/com/a2/nsocket/core/session/IoSession.java: -------------------------------------------------------------------------------- 1 | package com.a2.nsocket.core.session; 2 | 3 | 4 | import java.io.IOException; 5 | 6 | import com.a2.nsocket.core.handler.IoHandler; 7 | 8 | /** 9 | * process the interface of reading and writing 10 | * 11 | * @author ChenHui 12 | * 13 | */ 14 | public interface IoSession { 15 | 16 | IoHandler getHandler(); 17 | 18 | void write(Object message) throws IOException; 19 | 20 | void broadcast(Object message); 21 | 22 | Object read(); 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/a2/nsocket/core/session/NioAcceptorSession.java: -------------------------------------------------------------------------------- 1 | package com.a2.nsocket.core.session; 2 | 3 | import java.nio.channels.SelectionKey; 4 | import java.nio.channels.Selector; 5 | 6 | /** 7 | * this class direct implements IoSession TODO for abstract class 8 | * 9 | * @author ChenHui 10 | * 11 | */ 12 | public final class NioAcceptorSession extends AbstractIoSession implements SocketSession{ 13 | 14 | public final void setKey(SelectionKey key) { 15 | this.key = key; 16 | } 17 | 18 | public final void setSelecotr(Selector selector) { 19 | this.selector = selector; 20 | } 21 | 22 | public final void setIsServerChannel(boolean isServerChannel) { 23 | this.isServerChannel=isServerChannel; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/a2/nsocket/core/session/NioConnectorSession.java: -------------------------------------------------------------------------------- 1 | package com.a2.nsocket.core.session; 2 | 3 | import java.nio.channels.SelectionKey; 4 | import java.nio.channels.Selector; 5 | 6 | public final class NioConnectorSession extends AbstractIoSession implements SocketSession { 7 | 8 | public void setKey(SelectionKey key) { 9 | this.key=key; 10 | } 11 | 12 | public void setSelecotr(Selector selector) { 13 | this.selector=selector; 14 | } 15 | 16 | public void setIsServerChannel(boolean isServerChannel) { 17 | this.isServerChannel=false; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/a2/nsocket/core/session/SocketSession.java: -------------------------------------------------------------------------------- 1 | package com.a2.nsocket.core.session; 2 | 3 | import java.nio.channels.SelectionKey; 4 | import java.nio.channels.Selector; 5 | 6 | public interface SocketSession { 7 | 8 | void setKey(SelectionKey key); 9 | 10 | void setSelecotr(Selector selector); 11 | 12 | void setIsServerChannel(boolean isServerChannel); 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/a2/nsocket/nSocket.java: -------------------------------------------------------------------------------- 1 | package com.a2.nsocket; 2 | 3 | /** 4 | * Information for this project 5 | * @author ChenHui 6 | * 7 | */ 8 | public class nSocket { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/com/a2/nsocket/transport/socket/SocketAcceptor.java: -------------------------------------------------------------------------------- 1 | package com.a2.nsocket.transport.socket; 2 | 3 | import com.a2.nsocket.core.service.IoAcceptor; 4 | 5 | /** 6 | * interface for socket 7 | * @author ChenHui 8 | * 9 | */ 10 | public interface SocketAcceptor extends IoAcceptor{ 11 | 12 | public boolean isReuseAddress(); 13 | 14 | /**the size of backlog*/ 15 | public int getBacklog(); 16 | 17 | /**operate when the class is not bound*/ 18 | public void setBacklog(int backlog); 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/a2/nsocket/transport/socket/SocketConnector.java: -------------------------------------------------------------------------------- 1 | package com.a2.nsocket.transport.socket; 2 | 3 | import com.a2.nsocket.core.service.IoConnector; 4 | 5 | public interface SocketConnector extends IoConnector{ 6 | 7 | boolean isNonblocaking(); 8 | 9 | //TODO 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/com/a2/nsocket/transport/socket/nio/AioSocketAcceptor.java: -------------------------------------------------------------------------------- 1 | package com.a2.nsocket.transport.socket.nio; 2 | 3 | import java.net.SocketAddress; 4 | import java.util.Set; 5 | 6 | import com.a2.nsocket.core.handler.IoHandler; 7 | import com.a2.nsocket.core.service.AbstractIoAcceptor; 8 | import com.a2.nsocket.core.session.IoSession; 9 | import com.a2.nsocket.transport.socket.SocketAcceptor; 10 | 11 | public class AioSocketAcceptor extends AbstractIoAcceptor implements SocketAcceptor{ 12 | 13 | @Override 14 | protected IoSession bind0(Set localAddresses) { 15 | // TODO Auto-generated method stub 16 | return null; 17 | } 18 | 19 | @Override 20 | public void setHandler(IoHandler handler) { 21 | // TODO Auto-generated method stub 22 | 23 | } 24 | 25 | @Override 26 | public IoHandler getHandler() { 27 | // TODO Auto-generated method stub 28 | return null; 29 | } 30 | 31 | @Override 32 | public void init() throws Exception { 33 | // TODO Auto-generated method stub 34 | 35 | } 36 | 37 | @Override 38 | public boolean isBlocakingChannel() { 39 | // TODO Auto-generated method stub 40 | return false; 41 | } 42 | 43 | public boolean isReuseAddress() { 44 | // TODO Auto-generated method stub 45 | return false; 46 | } 47 | 48 | public int getBacklog() { 49 | // TODO Auto-generated method stub 50 | return 0; 51 | } 52 | 53 | public void setBacklog(int backlog) { 54 | // TODO Auto-generated method stub 55 | 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/com/a2/nsocket/transport/socket/nio/NioSocketAcceptor.java: -------------------------------------------------------------------------------- 1 | package com.a2.nsocket.transport.socket.nio; 2 | 3 | import java.io.IOException; 4 | import java.net.SocketAddress; 5 | import java.nio.channels.SelectionKey; 6 | import java.nio.channels.Selector; 7 | import java.nio.channels.ServerSocketChannel; 8 | import java.util.Set; 9 | import java.util.concurrent.Executor; 10 | import java.util.concurrent.Executors; 11 | 12 | import com.a2.nsocket.core.handler.IoHandler; 13 | import com.a2.nsocket.core.polling.NioSocketAcceptorPoll; 14 | import com.a2.nsocket.core.service.AbstractIoAcceptor; 15 | import com.a2.nsocket.core.session.IoSession; 16 | import com.a2.nsocket.core.session.NioAcceptorSession; 17 | import com.a2.nsocket.transport.socket.SocketAcceptor; 18 | 19 | public final class NioSocketAcceptor extends AbstractIoAcceptor implements 20 | SocketAcceptor { 21 | 22 | /** new session */ 23 | private IoSession session = null; 24 | private IoHandler handler = null; 25 | 26 | private ServerSocketChannel serverSocketChannel; 27 | private Selector selector; 28 | 29 | private Executor executor; 30 | 31 | public NioSocketAcceptor() { 32 | super(); 33 | try { 34 | serverSocketChannel = ServerSocketChannel.open(); 35 | selector = Selector.open(); 36 | session = new NioAcceptorSession(); 37 | executor = Executors.newCachedThreadPool(); 38 | } catch (IOException e) { 39 | e.printStackTrace(); 40 | } catch (Exception e) { 41 | e.printStackTrace(); 42 | } 43 | } 44 | 45 | @Override 46 | protected final IoSession bind0(Set localAddresses) { 47 | if (serverSocketChannel.isOpen() && selector.isOpen()) { 48 | try { 49 | serverSocketChannel.bind(localAddresses.iterator().next()); 50 | if (serverSocketChannel.isOpen() && selector.isOpen()) { 51 | serverSocketChannel.configureBlocking(false); 52 | serverSocketChannel.register(selector, 53 | SelectionKey.OP_ACCEPT); 54 | } 55 | // 56 | init(); 57 | } catch (IOException e) { 58 | e.printStackTrace(); 59 | } catch (Exception e) { 60 | e.printStackTrace(); 61 | } 62 | } 63 | return this.session; 64 | } 65 | 66 | @Override 67 | public boolean isBlocakingChannel() { 68 | return false; 69 | } 70 | 71 | @Override 72 | public void setHandler(IoHandler handler) { 73 | if (handler == null) { 74 | throw new IllegalArgumentException( 75 | "You need to add handler for this Communication"); 76 | } 77 | this.handler = handler; 78 | } 79 | 80 | @Override 81 | public IoHandler getHandler() { 82 | if (this.handler == null) { 83 | throw new IllegalArgumentException( 84 | "You need to add handler for this Communication"); 85 | } 86 | return this.handler; 87 | } 88 | 89 | @Override 90 | public void init() throws Exception { 91 | if (this.handler == null) { 92 | throw new IllegalArgumentException( 93 | "You need to add handler for this Communication"); 94 | } 95 | handler.sessionOpening(); 96 | executor.execute(new NioSocketAcceptorPoll(this.handler, this.session, 97 | this.selector)); 98 | } 99 | 100 | public boolean isReuseAddress() { 101 | // TODO Auto-generated method stub 102 | return false; 103 | } 104 | 105 | public int getBacklog() { 106 | // TODO Auto-generated method stub 107 | return 0; 108 | } 109 | 110 | public void setBacklog(int backlog) { 111 | // TODO Auto-generated method stub 112 | 113 | } 114 | 115 | } 116 | -------------------------------------------------------------------------------- /src/main/java/com/a2/nsocket/transport/socket/nio/NioSocketConnector.java: -------------------------------------------------------------------------------- 1 | package com.a2.nsocket.transport.socket.nio; 2 | 3 | import java.io.IOException; 4 | import java.net.SocketAddress; 5 | import java.nio.channels.SelectionKey; 6 | import java.nio.channels.Selector; 7 | import java.nio.channels.SocketChannel; 8 | import java.util.concurrent.Executor; 9 | import java.util.concurrent.Executors; 10 | 11 | import com.a2.nsocket.core.handler.IoHandler; 12 | import com.a2.nsocket.core.polling.NioSocketConnectorPoll; 13 | import com.a2.nsocket.core.service.AbstractIoConnector; 14 | import com.a2.nsocket.core.session.IoSession; 15 | import com.a2.nsocket.core.session.NioConnectorSession; 16 | import com.a2.nsocket.transport.socket.SocketConnector; 17 | 18 | public final class NioSocketConnector extends AbstractIoConnector implements 19 | SocketConnector { 20 | 21 | private IoHandler handler; 22 | private IoSession session; 23 | 24 | private SocketChannel channel; 25 | private Selector selector; 26 | 27 | private Executor executor; 28 | 29 | public NioSocketConnector() { 30 | 31 | try { 32 | session = new NioConnectorSession(); 33 | selector = Selector.open(); 34 | executor = Executors.newCachedThreadPool(); 35 | channel = SocketChannel.open(); 36 | } catch (IOException e) { 37 | e.printStackTrace(); 38 | } 39 | } 40 | 41 | /** this method should be considered */ 42 | public boolean isNonblocaking() { 43 | return true; 44 | } 45 | 46 | @Override 47 | protected IoSession connect0(SocketAddress remoteAddress) 48 | throws IOException { 49 | try { 50 | init(); 51 | } catch (Exception e) { 52 | e.printStackTrace(); 53 | } 54 | if (channel.isOpen() && selector.isOpen()) { 55 | channel.configureBlocking(false); 56 | channel.connect(remoteAddress); 57 | channel.register(selector, SelectionKey.OP_READ 58 | | SelectionKey.OP_WRITE); 59 | /** make sure */ 60 | while (!channel.finishConnect()) { 61 | 62 | } 63 | } 64 | executor.execute(new NioSocketConnectorPoll(this.handler, this.session, 65 | this.selector)); 66 | return this.session; 67 | } 68 | 69 | @Override 70 | protected void dispose0() throws IOException { 71 | // TODO Auto-generated method stub 72 | } 73 | 74 | @Override 75 | public void setHandler(IoHandler handler) { 76 | if (handler == null) { 77 | throw new IllegalArgumentException( 78 | "You need to add handler for this Communication"); 79 | } 80 | this.handler = handler; 81 | } 82 | 83 | @Override 84 | public IoHandler getHandler() { 85 | return this.handler; 86 | } 87 | 88 | @Override 89 | public void init() throws Exception { 90 | if (this.handler == null) { 91 | throw new IllegalArgumentException( 92 | "You need to add handler for this Communication"); 93 | } 94 | handler.sessionOpening(); 95 | } 96 | 97 | @Override 98 | public boolean isBlocakingChannel() { 99 | return false; 100 | } 101 | 102 | } 103 | -------------------------------------------------------------------------------- /src/main/java/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootLogger=info 2 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 3 | #log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 4 | ## Pattern to output the caller's file name and line number. 5 | ##log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n 6 | ## Print the date in ISO 8601 format 7 | #log4j.appender.stdout.layout.ConversionPattern=%d [%t] %-5p %c - %m%n 8 | #log4j.appender.R=org.apache.log4j.RollingFileAppender 9 | #log4j.appender.R.File=example.log 10 | #log4j.appender.R.MaxFileSize=100KB 11 | ## Keep one backup file 12 | #log4j.appender.R.MaxBackupIndex=1 13 | #log4j.appender.R.layout=org.apache.log4j.PatternLayout 14 | #log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n 15 | ## Print only messages of level WARN or above in the package com.foo. 16 | #log4j.logger.com.foo=WARN -------------------------------------------------------------------------------- /src/test/java/com/a2/nsocket/AppTest.java: -------------------------------------------------------------------------------- 1 | package com.a2.nsocket; 2 | 3 | import junit.framework.Test; 4 | import junit.framework.TestCase; 5 | import junit.framework.TestSuite; 6 | 7 | /** 8 | * Unit test for simple App. 9 | */ 10 | public class AppTest 11 | extends TestCase 12 | { 13 | /** 14 | * Create the test case 15 | * 16 | * @param testName name of the test case 17 | */ 18 | public AppTest( String testName ) 19 | { 20 | super( testName ); 21 | } 22 | 23 | /** 24 | * @return the suite of tests being tested 25 | */ 26 | public static Test suite() 27 | { 28 | return new TestSuite( AppTest.class ); 29 | } 30 | 31 | /** 32 | * Rigourous Test :-) 33 | */ 34 | public void testApp() 35 | { 36 | assertTrue( true ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/test/java/com/a2/nsocket/TestIoAcceptor.java: -------------------------------------------------------------------------------- 1 | package com.a2.nsocket; 2 | 3 | import java.io.IOException; 4 | import java.net.InetSocketAddress; 5 | import java.net.SocketAddress; 6 | import java.nio.ByteBuffer; 7 | 8 | import com.a2.nsocket.core.handler.IoHandlerAdapter; 9 | import com.a2.nsocket.core.service.IoAcceptor; 10 | import com.a2.nsocket.core.session.IoSession; 11 | import com.a2.nsocket.transport.socket.nio.NioSocketAcceptor; 12 | 13 | public class TestIoAcceptor extends IoHandlerAdapter{ 14 | 15 | @Override 16 | public void sessionOpening() throws Exception { 17 | System.out.println("session open..."); 18 | } 19 | 20 | @Override 21 | public void sessionOpened(IoSession session) throws Exception { 22 | session.write("welcome!!! \r\n"); 23 | } 24 | 25 | 26 | @Override 27 | public void messageReceive(IoSession session, Object message) 28 | throws Exception { 29 | ByteBuffer msg=ByteBuffer.allocate(1024); 30 | msg=(ByteBuffer) message; 31 | while(msg.hasRemaining()){ 32 | char s=(char)msg.get(); 33 | System.out.print(s); 34 | session.write(s); 35 | } 36 | msg.clear(); 37 | } 38 | 39 | 40 | public static void main(String[] args) throws IOException { 41 | 42 | SocketAddress net=new InetSocketAddress(8090); 43 | System.out.println(net); 44 | 45 | IoAcceptor acceptor=new NioSocketAcceptor(); 46 | acceptor.setLocalAddress(new InetSocketAddress(9020)); 47 | acceptor.setHandler(new TestIoAcceptor()); 48 | acceptor.bind(); 49 | 50 | System.out.println("linsening port..."+acceptor.getLocalAddress()); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/test/java/com/a2/nsocket/TestIoConnector.java: -------------------------------------------------------------------------------- 1 | package com.a2.nsocket; 2 | 3 | import java.io.IOException; 4 | import java.nio.ByteBuffer; 5 | 6 | import com.a2.nsocket.core.handler.IoHandlerAdapter; 7 | import com.a2.nsocket.core.service.IoConnector; 8 | import com.a2.nsocket.core.session.IoSession; 9 | import com.a2.nsocket.transport.socket.nio.NioSocketConnector; 10 | 11 | public class TestIoConnector extends IoHandlerAdapter{ 12 | 13 | @Override 14 | public void sessionOpening() throws Exception { 15 | System.out.println("connecting..."); 16 | } 17 | 18 | @Override 19 | public void messageReceive(IoSession session, Object message) 20 | throws Exception { 21 | ByteBuffer buf=(ByteBuffer) message; 22 | while(buf.hasRemaining()){ 23 | System.out.print((char)buf.get()); 24 | Thread.sleep(2000); 25 | } 26 | } 27 | 28 | @Override 29 | public void sessionOpened(IoSession session) throws Exception { 30 | session.write("I'm client"); 31 | } 32 | 33 | 34 | public static void main(String[] args) throws IOException, Exception { 35 | IoConnector connector=new NioSocketConnector(); 36 | connector.setHandler(new TestIoConnector()); 37 | connector.connect("127.0.0.1", 9020); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /target/classes/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootLogger=info 2 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 3 | #log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 4 | ## Pattern to output the caller's file name and line number. 5 | ##log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n 6 | ## Print the date in ISO 8601 format 7 | #log4j.appender.stdout.layout.ConversionPattern=%d [%t] %-5p %c - %m%n 8 | #log4j.appender.R=org.apache.log4j.RollingFileAppender 9 | #log4j.appender.R.File=example.log 10 | #log4j.appender.R.MaxFileSize=100KB 11 | ## Keep one backup file 12 | #log4j.appender.R.MaxBackupIndex=1 13 | #log4j.appender.R.layout=org.apache.log4j.PatternLayout 14 | #log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n 15 | ## Print only messages of level WARN or above in the package com.foo. 16 | #log4j.logger.com.foo=WARN --------------------------------------------------------------------------------