1 package com.ericsson.research.transport;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 import java.io.IOException;
37 import java.net.InetAddress;
38 import java.net.InetSocketAddress;
39 import java.net.UnknownHostException;
40 import java.nio.channels.SelectionKey;
41 import java.nio.channels.SocketChannel;
42
43 public class ManagedSocket implements NioEndpoint {
44
45 public static enum State { NOT_CONNECTED, CONNECTING, CONNECTED, DISCONNECTING }
46
47 private State mState;
48 private NioManager nioManager = NioManager.instance();
49 private SelectionKey key;
50 private InetSocketAddress mSocketAddress;
51 private ManagedSocketClient mClient;
52
53 public ManagedSocket() {
54 this(false);
55 }
56
57 protected ManagedSocket(boolean connected)
58 {
59 if (connected)
60 this.mState = State.CONNECTED;
61 else
62 this.mState = State.NOT_CONNECTED;
63 }
64
65 public void registerClient(ManagedSocketClient client) {
66 if (this.mClient != null)
67 return;
68 this.mClient = client;
69 }
70
71 public State getState() {
72 return this.mState;
73 }
74
75 public InetSocketAddress getInetAddress() {
76 return this.mSocketAddress;
77 }
78
79 public void connect(String host, int port) throws UnknownHostException {
80 this.connect(new InetSocketAddress(InetAddress.getByName(host), port));
81 }
82
83 public void connect(InetSocketAddress address) {
84 if (this.mState != State.NOT_CONNECTED)
85 throw new IllegalStateException("not connected");
86
87 if (this.mClient == null)
88 throw new IllegalStateException("Attempted to open a socket with no registered client");
89
90 this.mSocketAddress = address;
91 this.mState = State.CONNECTING;
92 this.nioManager.open(this, this.mSocketAddress);
93 }
94
95 public void write(byte[] data) throws IOException {
96 if (this.mState != State.CONNECTED)
97 throw new IllegalStateException("not connected");
98
99 this.write(data, data.length);
100 }
101
102 public void write(byte[] data, int size) throws IOException
103 {
104
105 if (this.key == null)
106 {
107 System.err.println("Breakpoint for debugging here");
108 return;
109 }
110
111 this.nioManager.send(this.key, data, size);
112 }
113
114 public void disconnect() {
115 if (this.mState == State.NOT_CONNECTED)
116
117
118 return;
119
120 this.mState = State.DISCONNECTING;
121
122
123 this.nioManager.close(this.key);
124 }
125
126
127 public NioEndpoint createAcceptChild()
128 {
129 return null;
130 }
131
132 public void notifyAccepted(NioEndpoint endpoint)
133 {
134 throw new IllegalAccessError();
135 }
136
137 public void notifyClosed()
138 {
139 if (this.mState == State.NOT_CONNECTED)
140 return;
141
142 this.mState = State.NOT_CONNECTED;
143 this.mClient.notifyDisconnected();
144 }
145
146 public void notifyConnected()
147 {
148 this.mState = State.CONNECTED;
149
150 this.mClient.notifyConnected();
151 }
152
153 public void notifyError(Exception e)
154 {
155 if (this.mState == State.NOT_CONNECTED)
156 return;
157
158 this.mState = State.NOT_CONNECTED;
159 this.mClient.notifyError(e);
160 }
161
162 public void receive(byte[] data, int size)
163 {
164 this.mClient.notifySocketData(data, size);
165 }
166
167 public void setNioManager(NioManager nioManager, SelectionKey key)
168 {
169 this.nioManager = nioManager;
170 this.key = key;
171 }
172
173 public boolean canAccept()
174 {
175 return false;
176 }
177
178
179
180
181 protected void finalize() throws Throwable
182 {
183 if (this.mState != State.NOT_CONNECTED)
184 {
185 this.mState = State.DISCONNECTING;
186 this.nioManager.close(this.key);
187 }
188 super.finalize();
189 }
190
191 public SelectionKey getKey()
192 {
193 return this.key;
194 }
195
196 public static byte[] copy(byte[] data, int size)
197 {
198 byte[] rv = new byte[size];
199 System.arraycopy(data, 0, rv, 0, size);
200 return rv;
201 }
202
203 public InetSocketAddress getLocalSocketAddress()
204 {
205 return (InetSocketAddress) ((SocketChannel) this.key.channel()).socket().getLocalSocketAddress();
206 }
207
208 public InetSocketAddress getRemoteSocketAddress()
209 {
210 return (InetSocketAddress) ((SocketChannel) this.key.channel()).socket().getRemoteSocketAddress();
211 }
212
213 }