/src/de/fau/cs/mad/fasl/libs/Net.java
Java | 401 lines | 260 code | 45 blank | 96 comment | 34 complexity | bcaf201a54e7f422326fa1f4b42fe5e3 MD5 | raw file
Possible License(s): Apache-2.0, LGPL-3.0
- /**
- * @file Net.java
- * @author Christian Dietrich <stettberger@dokucode.de>
- *
- * @brief Gives access to UDP and TCP communication
- *
- * Part of the FASL project and licensed under the GNU LGPL.
- * See README and COPYING.LESSER for details.
- */
- package de.fau.cs.mad.fasl.libs;
- import java.io.*;
- import java.net.*;
- // general settings
- import de.fau.cs.mad.fasl.LibraryClass;
- import de.fau.cs.mad.fasl.ast.AstType;
- import de.fau.cs.mad.fasl.interpreter.Scheduler;
- import de.fau.cs.mad.fasl.interpreter.Interpreter;
- import de.fau.cs.mad.fasl.libmanager.NeedsPermission;
- import de.fau.cs.mad.fasl.libmanager.IsLibraryMethod;
- import de.fau.cs.mad.fasl.libmanager.LibraryStruct;
- import de.fau.cs.mad.fasl.libmanager.IsLibraryStruct;
- import de.fau.cs.mad.fasl.libmanager.LibInfo;
- import android.Manifest.permission;
- /** The Net library provides access to UDP and TCP
- * communication. Client and server sockets are supported.
- *
- */
- public class Net extends LibraryClass
- {
- /** A udp socket handle
- */
- public static class UDPSocket extends LibraryStruct {
- private DatagramSocket clientSocket;
- public String lastSenderAddress;
- public Double lastSenderPort;
- }
- /**
- * Sends a UDP packet to a given ip address
- *
- * @param socket a udp socket
- * @param ipaddress a string identifying a remote machine
- * @param port UDP port
- * @param message the message that should be sent
- * @return whether the operation was a success
- */
- @IsLibraryMethod(params = "socket, ipaddress, port, message", description = "send udp packet")
- @NeedsPermission(permission.INTERNET)
- public static Boolean send(UDPSocket socket, String ipaddress, Double port, String message) {
- try {
- if (socket.clientSocket == null) {
- socket.clientSocket = new DatagramSocket();
- socket.clientSocket.setReuseAddress(true);
- }
- InetAddress IPAddress = InetAddress.getByName(ipaddress);
- byte[] sendData = message.getBytes();
- DatagramPacket sendPacket =
- new DatagramPacket(sendData, sendData.length, IPAddress, (int)(double)port);
- socket.clientSocket.send(sendPacket);
- } catch (UnknownHostException ex) {
- System.console("Unkown host: " + ipaddress);
- return false;
- } catch (IOException e) {
- System.console("UDP send failed:" + e);
- return false;
- }
- return true;
- }
- /**
- * Bind the UDP port to a certain port and ipaddress.
- *
- * @param socket a udp socket
- * @param ipaddress a string identifying a remote machine
- * @param port UDP port
- * @return whether the operation was a success
- */
- @IsLibraryMethod(params = "socket, ipaddress, port", description = "bind udp socket")
- @NeedsPermission(permission.INTERNET)
- public static Boolean bind(UDPSocket socket, String ipaddress, Double port) {
- try {
- InetAddress IPAddress = InetAddress.getByName(ipaddress);
- InetSocketAddress addr = new InetSocketAddress(IPAddress, (int)(double)port);
- socket.clientSocket = new DatagramSocket(addr);
- socket.clientSocket.setReuseAddress(true);
- } catch (UnknownHostException ex) {
- System.console("Unkown host: " + ipaddress);
- return false;
- } catch (IOException e) {
- System.console("UDP bin failed:" + e);
- return false;
- }
- return true;
- }
- /**
- * Receive UDP packet from previous bound socket. The sender of
- * the packet is stored within the socket. (lastSenderAddress,
- * lastSenderPort)
- *
- * @param socket a udp socket
- * @return The udp packet's content. null on error
- */
- @IsLibraryMethod(params = "socket", description = "receive udp packet")
- @NeedsPermission(permission.INTERNET)
- public static String receive(final UDPSocket socket) {
- if (socket == null || socket.clientSocket == null) {
- throw new IllegalArgumentException("socket must not be null");
- }
- final Scheduler scheduler = Scheduler.getInstance();
- final Interpreter current = scheduler.getCurrentTask();
- Thread t = new Thread() {
- @Override
- public void run() {
- try {
- byte[] receiveData = new byte[1600];
- DatagramPacket receivePacket =
- new DatagramPacket(receiveData, receiveData.length);
- socket.clientSocket.receive(receivePacket);
- String data = new String(receivePacket.getData());
- InetAddress IPAddress = receivePacket.getAddress();
- socket.lastSenderAddress = IPAddress.toString();
- socket.lastSenderPort = (double)receivePacket.getPort();
- if (!current.isTerminated()) {
- current.pushOntoStackFromLib(data, AstType.string);
- scheduler.awakeTask(current);
- }
- return;
- } catch (IOException e) {
- System.console("UDP bin failed:" + e);
- }
- if (!current.isTerminated()) {
- current.pushOntoStackFromLib(null, AstType.string);
- scheduler.awakeTask(current);
- }
- }
- };
- synchronized(scheduler) {
- t.start();
- // block current thread
- scheduler.pauseCurrentTask();
- return null; // never reached
- }
- }
- /**
- * Close a udp socket.
- *
- * @param socket a udp socket
- * @return The udp packet received. null on error
- */
- @IsLibraryMethod(params = "socket", description = "receive udp packet")
- public static void close(final UDPSocket socket) {
- if (socket == null) {
- return;
- }
- if (socket.clientSocket != null)
- socket.clientSocket.close();
- socket.clientSocket = null;
- }
- private static final AstType SocketType = LibInfo.libs.get("Net").structs.get("TCPClientSocket");
- /** A TCP server socket handle
- */
- @IsLibraryStruct(instantiable = false)
- public static class TCPServerSocket extends LibraryStruct {
- private final ServerSocket socket;
- // FIXME not that great
- public TCPServerSocket()
- {
- this(null);
- }
- public TCPServerSocket(ServerSocket socket) {
- this.socket = socket;
- }
- }
- /** A TCP client socket handle
- */
- @IsLibraryStruct(instantiable = false)
- public static class TCPClientSocket extends LibraryStruct {
- private final Socket socket;
- // FIXME not that great
- public TCPClientSocket()
- {
- this(null);
- }
- public TCPClientSocket(Socket socket) {
- this.socket = socket;
- }
- }
- /**
- * Creates a TCP server socket for a certain port
- *
- * @param port the port to usee
- * @return a server socket or null on failure
- */
- @IsLibraryMethod(params = "port", description = "creates a TCP server socket")
- @NeedsPermission(permission.INTERNET)
- public static final TCPServerSocket createServerSocket(Double port) {
- try {
- return new TCPServerSocket(new ServerSocket((int)(double)port));
- } catch (IOException e) {
- System.console("Net.createServerSocket: " + e.getMessage());
- }
- return null;
- }
- /**
- * Accepts a client connection on the server tcp socket.
- *
- * @param serverSocket the tcp server socket to accept a connection from
- * @return the client connection or null on failure
- */
- @IsLibraryMethod(params = "serverSocket", description = "accepts a TCP client connection")
- @NeedsPermission(permission.INTERNET)
- public static final TCPClientSocket accept(final TCPServerSocket serverSocket) {
- if (serverSocket == null || serverSocket.socket == null) {
- throw new IllegalArgumentException("socket must not be null");
- }
- final Scheduler scheduler = Scheduler.getInstance();
- final Interpreter current = scheduler.getCurrentTask();
- Thread t = new Thread() {
- public void run() {
- try {
- TCPClientSocket ret = new TCPClientSocket(serverSocket.socket.accept());
- if (!current.isTerminated()) {
- current.pushOntoStackFromLib(ret, SocketType);
- scheduler.awakeTask(current);
- }
- return;
- } catch (IOException e) {
- System.console("Net.accept: " + e.getMessage());
- }
- if (!current.isTerminated()) {
- current.pushOntoStackFromLib(null, SocketType);
- scheduler.awakeTask(current);
- }
- }
- };
- synchronized(scheduler) {
- t.start();
- scheduler.pauseCurrentTask();
- return null;
- }
- }
- /**
- * Creates a client socket connected to a specific host.
- *
- * @param ipAddress the ipAddress of the host
- * @param port the port of the host
- * @return the client socket or null on failure
- */
- @IsLibraryMethod(params = "ipAddress, port", description = "creates a TCP client socket for communicating with server")
- @NeedsPermission(permission.INTERNET)
- public static final TCPClientSocket createClientSocket(String ipAddress, Double port) {
- try {
- InetAddress ipaddr = InetAddress.getByName(ipAddress);
- return new TCPClientSocket(new Socket(ipaddr, (int)(double) port));
- } catch (UnknownHostException e) {
- System.console("Net.createClientSocket: unkown host");
- } catch (IOException e) {
- System.console("Net.createClientSocket: " + e.getMessage());
- }
- return null;
- }
- /**
- * Sends a message over the tcp socket
- *
- * @param socket the tcp socket to use
- * @param msg the message to send
- * @return true on successs, false on failure
- */
- @IsLibraryMethod(params = "socket, msg", description = "Sends a msg using the tcp socket")
- @NeedsPermission(permission.INTERNET)
- public static final Boolean send(TCPClientSocket socket, String msg) {
- if (socket == null || socket.socket == null) {
- throw new IllegalArgumentException("socket must not be null");
- }
- if (msg == null) {
- throw new IllegalArgumentException("msg must not be null");
- }
- try {
- PrintWriter out = new PrintWriter(socket.socket.getOutputStream());
- out.write(msg);
- out.flush();
- return true;
- } catch (IOException e) {
- System.console("Net.send: " + e.getMessage());
- }
- return false;
- }
- /**
- * Receives a message from a tcp socket
- *
- * @param socket the tcp socket to receive the message from
- * @return the message of null on failure
- */
- @IsLibraryMethod(params = "socket", description = "Receive a msg from the tcp socket")
- @NeedsPermission(permission.INTERNET)
- public static final String receive(final TCPClientSocket socket) {
- if (socket == null || socket.socket == null) {
- throw new IllegalArgumentException("socket must not be null");
- }
- final Scheduler scheduler = Scheduler.getInstance();
- final Interpreter current = scheduler.getCurrentTask();
- Thread t = new Thread() {
- public void run() {
- try {
- BufferedReader in = new BufferedReader(new InputStreamReader(
- socket.socket.getInputStream()));
- char buffer[] = new char[300];
- int count = in.read(buffer, 0, 300);
- String ret = new String(buffer, 0, count);
- if (!current.isTerminated()) {
- current.pushOntoStackFromLib(ret, AstType.string);
- scheduler.awakeTask(current);
- }
- return;
- } catch (IOException e) {
- System.console("Net.recv: " + e.getMessage());
- }
- if (!current.isTerminated()) {
- current.pushOntoStackFromLib(null, AstType.string);
- scheduler.awakeTask(current);
- }
- }
- };
- synchronized(scheduler) {
- t.start();
- scheduler.pauseCurrentTask();
- return null;
- }
- }
- /**
- * Closes a tcp server socket.
- *
- * @param socket the socket to close
- */
- @IsLibraryMethod(params = "socket", description = "Closes the server socket")
- public static final void close(TCPServerSocket socket) {
- if (socket == null)
- return;
- try {
- socket.socket.close();
- } catch (IOException e) {
- }
- }
- /**
- * Closes a tcp client socket.
- *
- * @param socket the socket to close
- */
- @IsLibraryMethod(params = "socket", description = "Closes the client socket")
- public static final void close(TCPClientSocket socket) {
- if (socket == null)
- return;
- try {
- socket.socket.close();
- } catch (IOException e) {
- }
- }
- }