OSDN Git Service

lejos_NXJ_win32_0_5_0beta.zip
[nxt-jsp/lejos_nxj.git] / nxtOSEK / lejos_nxj / src / java / pctools / lejos / pc / tools / SocketProxy.java
1 package lejos.pc.tools;\r
2 \r
3 import java.io.*;\r
4 import java.net.*;\r
5 import lejos.pc.comm.*;\r
6 \r
7 /**\r
8 * Socket Proxy for NXT\r
9 * Has two main functions. The first is to connect to an existing\r
10 * server socket on the specified port. The second function is to\r
11 * create a socket server. In this case the proxy assumes that the\r
12 * NXT will then send a command to inform the proxy of the next action\r
13 * to take\r
14 *\r
15 * Currently only supports TCP connections\r
16 *\r
17 * @author Ranulf Green\r
18 * @version 1.0\r
19 */\r
20 public class SocketProxy {\r
21 \r
22         private String host;\r
23         private int port;\r
24         private DataInputStream inFromNXT;\r
25         private DataOutputStream outToNXT;\r
26         private ServerSocket serverSocket;\r
27         private Socket sock;\r
28 \r
29         /**\r
30          * Constructor\r
31          * An instance of Socket proxy will allow for transparent forwarding\r
32          * of messages between server and NXT using a socket connection\r
33          * @param NXTName The name of the NXT to connect to\r
34          * @param NXTaddress The physical address of the NXT\r
35          */\r
36         public SocketProxy(String NXTName, String NXTaddress){\r
37                 try {\r
38                         //  create a Bluetooth connection with the NXT\r
39                         NXTComm nxtComm = NXTCommFactory.createNXTComm(NXTCommFactory.BLUETOOTH);\r
40                         NXTInfo[] nxtInfo = new NXTInfo[1];\r
41 \r
42                         nxtInfo[0] = new NXTInfo(NXTName,NXTaddress);\r
43 \r
44                         System.out.println("Connecting to " + nxtInfo[0].btResourceString);\r
45 \r
46                         // check to see if NXT really exists, if not exit\r
47                         boolean isOpen = false;\r
48                         try {\r
49                                 isOpen = nxtComm.open(nxtInfo[0]);\r
50                         } catch(NXTCommException n) {\r
51                                 System.err.println(n.getMessage());\r
52                                 isOpen = false;\r
53                         }\r
54                         if (!isOpen) {\r
55                                 System.out.println("Failed to open " + nxtInfo[0].name);\r
56                                 System.exit(1);\r
57                         }\r
58 \r
59                         inFromNXT = new DataInputStream(nxtComm.getInputStream());\r
60                         outToNXT = new DataOutputStream(nxtComm.getOutputStream());\r
61                         \r
62                         // check to see if socket is a server or a client\r
63                         boolean isServer = inFromNXT.readBoolean();\r
64                         if(isServer){\r
65                                 newSocketServer();\r
66                         }else{\r
67                                 newSocketConnection();\r
68                         }\r
69                 }\r
70                 catch (UnknownHostException e) {e.printStackTrace();}\r
71                 catch (IOException e) {e.printStackTrace();}\r
72         }\r
73 \r
74         /**\r
75          * Creates a new socket server if instructed by the NXT\r
76          * @throws IOException\r
77          */\r
78         private void newSocketServer() throws IOException{\r
79                 int port = inFromNXT.readInt();\r
80                 serverSocket = new ServerSocket(port);\r
81                 boolean cmdMode = true;\r
82                 while(cmdMode){\r
83                         // wait for command from NXT\r
84                         byte command = inFromNXT.readByte();\r
85                         if(command == 1){\r
86                                 waitForConnection();\r
87                                 cmdMode = false;\r
88                         }\r
89                         // TODO support for other socket server functions\r
90                 }\r
91         }\r
92 \r
93         /**\r
94          * Allows negotiation of the accept() method of Socket server\r
95          * @throws IOException\r
96          */\r
97         private void waitForConnection()throws IOException{\r
98                 while(true){\r
99                         sock = serverSocket.accept();\r
100 \r
101                         //      inform the NXT of the new Connection\r
102                         outToNXT.writeBoolean(true);\r
103                         outToNXT.flush();\r
104 \r
105                         DataInputStream inFromSocket = new DataInputStream(sock.getInputStream());\r
106                         DataOutputStream outToSocket = new DataOutputStream(sock.getOutputStream());\r
107 \r
108                         // listen for incoming data from socket\r
109                         new forward(sock, inFromSocket, outToNXT);\r
110 \r
111                         // listen for incoming data from NXT\r
112                         new forwardNXT(sock, inFromNXT, outToSocket);\r
113                 }\r
114         }\r
115 \r
116         /**\r
117          * Allows for a connection to be made using the details supplied from the NXT\r
118          * @throws UnknownHostException\r
119          * @throws IOException\r
120          */\r
121         private void newSocketConnection() throws UnknownHostException, IOException \r
122         {\r
123                 // the first byte from the NXT contains the length of the host name in chars\r
124                 int len = inFromNXT.readByte();\r
125                 char[] hostChars = new char[len];\r
126 \r
127                 // following the first byte the host name is transmitted\r
128                 for(int i=0;i<len;i++){\r
129                         hostChars[i] = inFromNXT.readChar();\r
130                 }\r
131                 // following the host name an int containing the port number of the socket to connect to\r
132                 // is transmitted\r
133                 port = inFromNXT.readInt();\r
134                 host = new String(hostChars);\r
135 \r
136                 System.out.println("Host: " + host + " port: " + port);\r
137                 // create a socket connection with the specified host using the specified port\r
138 \r
139                 sock = new Socket(host, port);\r
140                 outToNXT.writeBoolean(true);\r
141                 outToNXT.flush();\r
142 \r
143                 DataInputStream inFromSocket = new DataInputStream(sock.getInputStream());\r
144 \r
145                 DataOutputStream outToSocket = new \r
146                 DataOutputStream(sock.getOutputStream());\r
147 \r
148                 // listen for incoming data from socket\r
149                 new forward(sock, inFromSocket, outToNXT);\r
150 \r
151                 // listen for incoming data from NXT\r
152                 new forwardNXT(sock, inFromNXT, outToSocket);\r
153         }\r
154 \r
155         /**\r
156          * Allows for the forwarding of messages from Socket to NXT\r
157          * @author Ranulf Green\r
158          */\r
159         private class forward extends Thread{\r
160                 private DataOutputStream dout;\r
161                 private DataInputStream din;\r
162 \r
163                 private Socket sock;\r
164 \r
165                 /**\r
166                  * Constructor.\r
167                  * @param sock the socket with which the connection is made\r
168                  * @param dis the input stream to read\r
169                  * @param dos the output stream to forward to\r
170                  */\r
171                 public forward(Socket sock, DataInputStream dis, DataOutputStream dos){\r
172                         super();\r
173                         din=dis;\r
174                         dout=dos;\r
175                         this.sock = sock;\r
176                         start();\r
177                 }\r
178                 /**\r
179                  * Causes a new thread to be invoked\r
180                  */\r
181                 public void run(){\r
182                         try{\r
183                                 boolean flushed = true;\r
184                                 while(true){\r
185                                         int a = din.available();\r
186                                         if(a>0){\r
187                                                 //System.out.println("Reading!" + a);\r
188                                                 flushed = false;\r
189                                                 int in = din.readUnsignedByte();\r
190                                                 if(in<0){\r
191                                                         //System.out.println("In Thread: Socket closed:" + in);\r
192                                                         sock.close();\r
193                                                         return;\r
194                                                 }\r
195                                                 //System.out.println("Sending " + in);\r
196                                                 dout.writeByte(in);\r
197                                         }else if(!flushed){\r
198                                                 //System.out.println("Flushing");\r
199                                                 dout.flush();\r
200                                                 flushed = true;\r
201                                         }\r
202                                         try {\r
203                                                 Thread.sleep(100);\r
204                                                 Thread.yield();\r
205                                         } catch (InterruptedException e) {}\r
206                                 }\r
207                         }catch(IOException ioe){ioe.printStackTrace();};\r
208                 }\r
209         }\r
210 \r
211         /**\r
212          * Class to forward messages from NXT to socket\r
213          * @author Ranulf Green\r
214          *\r
215          */\r
216         private class forwardNXT extends Thread{\r
217                 private DataOutputStream dout;\r
218                 private DataInputStream din;\r
219 \r
220                 private Socket sock;\r
221 \r
222                 /**\r
223                  * Constructor.\r
224                  * @param sock\r
225                  * @param dis input stream from NXT\r
226                  * @param dos output stream to socket\r
227                  */\r
228                 public forwardNXT(Socket sock, DataInputStream dis, DataOutputStream dos){\r
229                         super();\r
230                         din=dis;\r
231                         dout=dos;\r
232                         this.sock = sock;\r
233                         start();\r
234                 }\r
235 \r
236                 /**\r
237                  * causes a new thread to be invoked\r
238                  */\r
239                 public void run(){\r
240                         try{\r
241                                 while(true){\r
242                                         int in = din.readUnsignedByte();\r
243                                         if(in<0){\r
244                                                 System.out.println("In Thread: Socket closed:" + in);\r
245                                                 sock.close();\r
246                                                 return;\r
247                                         }\r
248                                         if(in!=0){\r
249                                                 dout.writeByte(in);\r
250                                                 dout.flush();\r
251                                         }\r
252                                         try {\r
253                                                 Thread.sleep(10);\r
254                                                 Thread.yield();\r
255                                         } catch (InterruptedException e) {}\r
256                                 }\r
257                         }catch(IOException ioe){ioe.printStackTrace();};\r
258                 }\r
259         }\r
260 \r
261         public static void main(String[] args) {\r
262                 if(args.length!=2){\r
263                         System.out.println("USAGE: java SocketProxy <NXTName> <NXTAddress>");\r
264                         System.exit(0);\r
265                 }\r
266                 new SocketProxy(args[0],args[1]);\r
267         }\r
268 }\r
269 \r
270 \r
271 \r