Stdlib/implement simple socket server (#4)
* Simple socket server with a test client
This commit is contained in:
parent
8f027bace3
commit
0566946c73
8 changed files with 180 additions and 1 deletions
|
@ -1,5 +1,7 @@
|
||||||
package com.jsaasta.froj.stdlib;
|
package com.jsaasta.froj.stdlib;
|
||||||
|
|
||||||
|
import com.jsaasta.froj.stdlib.socket.SocketServer;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
@ -12,6 +14,7 @@ public class Stdlib {
|
||||||
classes.put("clock", new Clock());
|
classes.put("clock", new Clock());
|
||||||
classes.put("input", new Input());
|
classes.put("input", new Input());
|
||||||
classes.put("fileReader", new FileReader());
|
classes.put("fileReader", new FileReader());
|
||||||
|
classes.put("socket", new SocketServer());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Map<String, Object> define(){
|
public static Map<String, Object> define(){
|
||||||
|
|
39
src/com/jsaasta/froj/stdlib/socket/ClientHandler.java
Normal file
39
src/com/jsaasta/froj/stdlib/socket/ClientHandler.java
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
package com.jsaasta.froj.stdlib.socket;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.net.Socket;
|
||||||
|
|
||||||
|
class ClientHandler implements Runnable {
|
||||||
|
private Socket socket;
|
||||||
|
|
||||||
|
public ClientHandler(Socket socket) {
|
||||||
|
this.socket = socket;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
InputStream in = socket.getInputStream();
|
||||||
|
OutputStream out = socket.getOutputStream();
|
||||||
|
|
||||||
|
byte[] buffer = new byte[1024];
|
||||||
|
int bytesRead = in.read(buffer);
|
||||||
|
if (bytesRead == -1) {
|
||||||
|
System.out.println("Client closed the Connection");
|
||||||
|
}
|
||||||
|
|
||||||
|
String message = new String(buffer, 0, bytesRead);
|
||||||
|
System.out.println("Received message from client: " + message);
|
||||||
|
|
||||||
|
out.write(message.getBytes());
|
||||||
|
|
||||||
|
SocketServer.messageQueue.put(message);
|
||||||
|
|
||||||
|
socket.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.out.println("Error handling client connection: " + e.getMessage());
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
72
src/com/jsaasta/froj/stdlib/socket/SocketServer.java
Normal file
72
src/com/jsaasta/froj/stdlib/socket/SocketServer.java
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
package com.jsaasta.froj.stdlib.socket;
|
||||||
|
|
||||||
|
import com.jsaasta.froj.FrojCallable;
|
||||||
|
import com.jsaasta.froj.Interpreter;
|
||||||
|
import com.jsaasta.froj.stdlib.StdlibRuntimeError;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.ServerSocket;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.BlockingQueue;
|
||||||
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
|
|
||||||
|
public class SocketServer implements FrojCallable {
|
||||||
|
protected static BlockingQueue<String> messageQueue = new LinkedBlockingQueue<>();
|
||||||
|
private static ServerSocket serverSocket;
|
||||||
|
|
||||||
|
private final String EXIT_CODE = "EXIT";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int arity() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object call(Interpreter interpreter, List<Object> arguments) {
|
||||||
|
return startSocketServer(arguments.get(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object startSocketServer(Object port) {
|
||||||
|
try {
|
||||||
|
Double param = (Double) port;
|
||||||
|
final int PORT = param.intValue();
|
||||||
|
|
||||||
|
serverSocket = new ServerSocket(PORT);
|
||||||
|
|
||||||
|
Socket socket = serverSocket.accept();
|
||||||
|
System.out.println("Incoming connection from " + socket.getInetAddress());
|
||||||
|
|
||||||
|
ClientHandler clientHandler = new ClientHandler(socket);
|
||||||
|
clientHandler.run();
|
||||||
|
String nextMessage = getNextMessage();
|
||||||
|
if (nextMessage.toLowerCase().contentEquals("exit")) {
|
||||||
|
shutdown();
|
||||||
|
return EXIT_CODE;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return Double.parseDouble(nextMessage);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
return nextMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (IOException | InterruptedException e) {
|
||||||
|
throw new StdlibRuntimeError(e.getMessage());
|
||||||
|
} finally {
|
||||||
|
shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getNextMessage() throws InterruptedException {
|
||||||
|
return messageQueue.take();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void shutdown() {
|
||||||
|
try {
|
||||||
|
serverSocket.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.out.println("Error shutting down server: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
58
src/com/jsaasta/tool/SocketClient.java
Normal file
58
src/com/jsaasta/tool/SocketClient.java
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
package com.jsaasta.tool;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.net.ConnectException;
|
||||||
|
import java.net.Socket;
|
||||||
|
|
||||||
|
class SocketClient {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws IOException {
|
||||||
|
while(true) {
|
||||||
|
InputStreamReader input = new InputStreamReader(System.in);
|
||||||
|
BufferedReader reader = new BufferedReader(input);
|
||||||
|
|
||||||
|
String message = reader.readLine();
|
||||||
|
if(message.contentEquals("SHUTMEDOWN")){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
String response = sendMessage(message);
|
||||||
|
if (response != null) {
|
||||||
|
System.out.println("Received response from server: " + response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String sendMessage(String message) throws IOException {
|
||||||
|
Socket socket = null;
|
||||||
|
try {
|
||||||
|
socket = new Socket("localhost", 8000);
|
||||||
|
System.out.println("Connected to server");
|
||||||
|
|
||||||
|
OutputStream out = socket.getOutputStream();
|
||||||
|
InputStream in = socket.getInputStream();
|
||||||
|
|
||||||
|
out.write(message.getBytes());
|
||||||
|
|
||||||
|
byte[] buffer = new byte[1024];
|
||||||
|
int bytesRead = in.read(buffer);
|
||||||
|
String response = new String(buffer, 0, bytesRead);
|
||||||
|
|
||||||
|
return response;
|
||||||
|
} catch (ConnectException e) {
|
||||||
|
System.out.println("Connection refused. Is the server running?");
|
||||||
|
return null;
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.out.println("Error sending message: " + e.getMessage());
|
||||||
|
return null;
|
||||||
|
} finally {
|
||||||
|
if (socket != null) {
|
||||||
|
try {
|
||||||
|
socket.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.out.println("Error closing socket: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -13,6 +13,12 @@ public class FrojStdlibTest {
|
||||||
public void test_Stdlib_Clock() throws IOException {
|
public void test_Stdlib_Clock() throws IOException {
|
||||||
Froj froj = new Froj();
|
Froj froj = new Froj();
|
||||||
froj.runFile("src/test/com/saasta/froj/stdlib/froj_stdlib_clock.froj");
|
froj.runFile("src/test/com/saasta/froj/stdlib/froj_stdlib_clock.froj");
|
||||||
|
froj.runFile("src/test/com/saasta/froj/stdlib/froj_stdlib_fileReader.froj");
|
||||||
|
try {
|
||||||
|
froj.runFile("src/test/com/saasta/froj/stdlib/froj_stdlib_socketserver.froj");
|
||||||
|
} catch(NullPointerException ex){
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
fileReader("./hello_world.froj");
|
|
@ -1 +0,0 @@
|
||||||
input();
|
|
|
@ -0,0 +1 @@
|
||||||
|
socket("asdf");
|
Loading…
Reference in a new issue