Skip to content

Instantly share code, notes, and snippets.

@streamerd
Created April 3, 2017 10:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save streamerd/4df24722818de351dbe1d753d2d6e849 to your computer and use it in GitHub Desktop.
Save streamerd/4df24722818de351dbe1d753d2d6e849 to your computer and use it in GitHub Desktop.
SocketCastify created by streamerd - https://repl.it/Grjk/3
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws InterruptedException, IOException {
File file = new File("nodeIpAddresses");
BufferedWriter bw = new BufferedWriter(new FileWriter(file));
for (int i = 0; i < 10; i++) {
bw.write("127.0.0.1 " + (5000 + i));
bw.newLine();
}
bw.close();
BufferedReader br = new BufferedReader(new FileReader(file));
while (br.ready()) {
String[] split = br.readLine().split(" ");
int portNumber = Integer.parseInt(split[1]);
new Thread(new Node(file.getPath(), portNumber)).start();
}
br.close();
}
}
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class Node implements Runnable {
private static final String WAIT_RESPONSE = "wait";
private static final String AFFIRMATIVE_RESPONSE = "printed";
private static final String NEGATIVE_RESPONSE = "negative";
private static final String AFFIRMATIVE_MESSAGE = AFFIRMATIVE_RESPONSE + "\n";
private static final String WAIT_MESSAGE = WAIT_RESPONSE + "\n";
private static final String NEGATIVE_MESSAGE = NEGATIVE_RESPONSE + "\n";
private static final long WAIT_TIME = 500;
private ServerSocket serverSocket;
private boolean isPrinted = false;
private final String ipAddressesFile;
private final int portNumber;
private long creationTime;
// Constructor for a Node: requires ipAddressesFile and portNumber. Also creationTime is kept for deciding on its age.
public Node(String ipAddressesFile, int portNumber) {
this.ipAddressesFile = ipAddressesFile;
this.portNumber = portNumber;
creationTime = System.currentTimeMillis();
}
// Node class implements Runnable.
// <<<<< run#1 >>>>>>>>>
@Override
public void run() {
try {
// run method here first forces a thread to sleep here for a random time, within 1000 ms of interval.
Thread.sleep(Math.abs(new Random().nextLong() % 1000));
} catch (InterruptedException e1) {
}
new Thread(new Runnable() { //this thread initializes the socket communication; by calling initServerSocket method.
@Override
public void run() {
try {
initServerSocket();
} catch (IOException e) {
}
}
}).start();
// within the run#1 method,
new Thread(new Runnable() {
List<NodeInfo> readOtherNodesInfo = readOtherNodesInfo(ipAddressesFile);
public void run() {
isPrinted = checkIfPrinted(readOtherNodesInfo);
if (isPrinted) {
System.out.println("other machine printed " + portNumber + " " + creationTime);
} else {
isPrinted = true;
System.out.println("we are started " + portNumber + " " + creationTime);
}
}
}).start();
} // <<<<<<<<< end of run#1 >>>>>>>>>>>>>>>>>
public void initServerSocket() throws IOException {
serverSocket = new ServerSocket(portNumber);
while (true) {
Socket connectionSocket = serverSocket.accept();
new Thread(new Runnable() {
@Override
public void run() {
try {
BufferedReader inFromClient = new BufferedReader(
new InputStreamReader(connectionSocket.getInputStream()));
DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
while (true) {
String message = inFromClient.readLine();
long creation = Long.parseLong(message);
outToClient = new DataOutputStream(connectionSocket.getOutputStream());
if (isPrinted)
outToClient.writeBytes(AFFIRMATIVE_MESSAGE);
else if (creation < creationTime)
outToClient.writeBytes(WAIT_MESSAGE);
else
outToClient.writeBytes(NEGATIVE_MESSAGE);
}
} catch (NumberFormatException e) {
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
}
private boolean checkIfPrinted(List<NodeInfo> readOtherNodesInfo) {
for (NodeInfo nodeInfo : readOtherNodesInfo) {
try {
Socket clientSocket = new Socket(nodeInfo.ipAddress, nodeInfo.portNumber);
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
whileloop: {
while (true) {
outToServer.writeBytes(Long.toString(creationTime) + "\n");
String response = inFromServer.readLine();
switch (response) {
case WAIT_RESPONSE:
Thread.sleep(WAIT_TIME);
break;
case AFFIRMATIVE_RESPONSE:
clientSocket.close();
System.out.println("aff massage from " + nodeInfo.portNumber);
return true;
case NEGATIVE_RESPONSE:
clientSocket.close();
break whileloop;
default:
assert(false);
}
}
}
} catch (Exception e) {
continue;
}
}
return false;
}
//
private List<NodeInfo> readOtherNodesInfo(String filePath) {
List<NodeInfo> otherNodes = new ArrayList<>();
try {
BufferedReader br = new BufferedReader(new FileReader(new File(filePath)));
while (br.ready()) {
String readLine = br.readLine();
String[] split = readLine.split(" ");
otherNodes.add(new NodeInfo(split[0], split[1]));
}
br.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return otherNodes;
}
//NodeInfo is an inner class to define a data structure for a socket (Ip address & port number)
class NodeInfo {
String ipAddress;
int portNumber;
public NodeInfo(String ipAddress, String portNumber) {
this.ipAddress = ipAddress;
this.portNumber = Integer.parseInt(portNumber);
}
}
public static void main(String[] args) {
if (args.length != 2) {
System.out.println("Usage of this program is: {path to ip addresses file} {portnumber to run}");
System.exit(0);
}
//ipAddressesFile file's path is fetched as the first argument, of type: String.,
//and portNumber is passed as an integer.
String ipAddressesFile = args[0];
int portNumber = Integer.parseInt(args[1]);
System.out.print("Node started: ");
System.out.print(ipAddressesFile + " ");
System.out.println(portNumber);
//When the valid arguments are given to the main function, a new node is instantiated with the run method.
new Node(ipAddressesFile, portNumber).run();
}
}
127.0.0.1 5000
127.0.0.1 5001
127.0.0.1 5002
127.0.0.1 5003
127.0.0.1 5004
127.0.0.1 5005
127.0.0.1 5006
127.0.0.1 5007
127.0.0.1 5008
127.0.0.1 5009
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment