├── .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 |
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
--------------------------------------------------------------------------------