blob: 877f1b952c82dc4d036fec269295bd2ce54444bb [file] [log] [blame]
// JavaSocketBridge.java
// by Stephen Ware
// April 25, 2009
//
// Part of the JavaSocketBridge project.
// This applet provides an interface for using true sockets in JavaScript.
//
// Note: You will need to have the Java Plugin archive in your classpath to compile this.
// For me, that's C:\Program Files\Java\jre6\lib\plugin.jar
// Note: You will need to jar this class and Listener.class into a signed jar file if
// you want your sockets to access domains other than the one this is running on.
// Note: Apparently, when you grant permissions to Java applets in Java 6, you only grant
// them to the main applet thread. That's the reason for all the confusing stuff
// in the connect methods... so that connections always happen on the main thread.
import java.applet.*;
import javax.swing.*;
import netscape.javascript.*;
import java.net.*;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.io.*;
public class JavaSocketBridge extends JApplet {
private final static int PACKETSIZE = 3000 ;
// Instance variables
JSObject browser = null; // The browser
// Initialize
public void init(){
browser = JSObject.getWindow(this);
}
public String connectAndStart(final String ip, final int por, final String interest){
return AccessController.doPrivileged(
new PrivilegedAction<String>() {
public String run() {
DatagramSocket socket = null ;
byte[] output = null;
try
{
// Convert the arguments first, to ensure that they are valid
InetAddress host = InetAddress.getByName( ip ) ;
int port = por ;
// Construct the socket
socket = new DatagramSocket() ;
byte [] data = hex2Byte(interest);
DatagramPacket packet = new DatagramPacket( data, data.length, host, port ) ;
// Send it
socket.send( packet ) ;
// Set a receive timeout, 2000 milliseconds
socket.setSoTimeout( 2000 ) ;
// Prepare the packet for receive
packet.setData( new byte[PACKETSIZE] ) ;
// Wait for a response from the server
socket.receive( packet ) ;
// Print the response
output = packet.getData() ;
}
catch( Exception e )
{
error(e.toString());
System.out.println( e ) ;
}
finally
{
if( socket != null )
socket.close() ;
}
if(output!=null)
return byte2hex(output);
else
return "";
}
}
);
}
public static byte[] hex2Byte(String str)
{
byte[] bytes = new byte[str.length() / 2];
for (int i = 0; i < bytes.length; i++)
{
bytes[i] = (byte) Integer
.parseInt(str.substring(2 * i, 2 * i + 2), 16);
}
return bytes;
}
public static String byte2hex(byte[] b)
{
// String Buffer can be used instead
String hs = "";
String stmp = "";
for (int n = 0; n < b.length; n++)
{
stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
if (stmp.length() == 1)
{
hs = hs + "0" + stmp;
}
else
{
hs = hs + stmp;
}
if (n < b.length - 1)
{
hs = hs + "";
}
}
return hs;
}
// Main
// Note: This method loops over and over to handle requests becuase only
// this thread gets the elevated security policy. Java == stupid.
public void start(){
try {
browser.call("java_socket_bridge_ready", null);
} catch (JSException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// Report an error
public void error(String message){
message = "Java Socket Bridge ERROR: " + message;
Object[] arguments = new Object[1];
arguments[0] = message;
try {
browser.call("on_socket_error", arguments);
} catch (JSException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}