-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add Networking to proj3 for remote game sharing
- Loading branch information
Showing
2 changed files
with
292 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
package byow.Networking; | ||
|
||
import edu.princeton.cs.introcs.StdDraw; | ||
|
||
import java.awt.*; | ||
import java.io.*; | ||
import java.net.Socket; | ||
import java.nio.file.Paths; | ||
import java.util.Scanner; | ||
|
||
/** | ||
* Created by Boren Tsai and Arjun Sahai. | ||
*/ | ||
|
||
public class BYOWClient { | ||
private int width; | ||
private int height; | ||
|
||
private Socket clientStringSocket; | ||
private Socket clientReadSocket; | ||
private BufferedWriter out; | ||
private BufferedReader in; | ||
private DataInputStream dis; | ||
|
||
static public final String CANVAS_FILE = ".client_canvas"; | ||
|
||
static final String canvasPath = join(new File(System.getProperty("user.dir")), CANVAS_FILE).getAbsolutePath(); | ||
static int magic = Integer.MIN_VALUE; | ||
|
||
/* | ||
Open socket, input/output streams, and create buffered writer & data input streams. | ||
*/ | ||
public void startConnection(String ip, int port) throws IOException { | ||
clientReadSocket = new Socket(ip, port); | ||
clientStringSocket = new Socket(ip, port); | ||
dis = new DataInputStream(clientReadSocket.getInputStream()); | ||
out = new BufferedWriter(new OutputStreamWriter(clientStringSocket.getOutputStream())); | ||
in = new BufferedReader(new InputStreamReader(clientStringSocket.getInputStream())); | ||
} | ||
|
||
/* | ||
Check that the server has acknowledged that it is quitting in a nonblocking fasion | ||
*/ | ||
private boolean shouldClose() throws IOException { | ||
if (in.ready()) { | ||
char[] buf = new char[4]; | ||
in.read(buf, 0, 4); // block client | ||
System.out.println(String.copyValueOf(buf)); | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
/* | ||
Close reader and writer then close socket. | ||
*/ | ||
private void stopConnection() throws IOException { | ||
dis.close(); | ||
out.close(); | ||
clientReadSocket.close(); | ||
clientStringSocket.close(); | ||
} | ||
|
||
/* | ||
Non Blocking | ||
Sends a String Command to the server i.e. W, A, S, D, etc. | ||
*/ | ||
private void sendCommand(String msg) throws IOException { | ||
out.write(msg); | ||
out.flush(); | ||
} | ||
|
||
/* | ||
Blocking | ||
Displays a canvas if the server has sent the client something to read | ||
i.e. The server has sent a png file to the client | ||
*/ | ||
private void showCanvas() throws IOException { | ||
if (dis.available() > 0) { | ||
boolean configure = dis.readBoolean(); | ||
if (configure) { | ||
System.out.println("CONFIGURING CANVAS"); | ||
width = dis.readInt(); | ||
height = dis.readInt(); | ||
StdDraw.setCanvasSize(width, height); | ||
StdDraw.setXscale(0, width); | ||
StdDraw.setYscale(0, height); | ||
StdDraw.clear(new Color(0, 0, 0)); | ||
StdDraw.enableDoubleBuffering(); | ||
StdDraw.show(); | ||
} | ||
|
||
StdDraw.clear(); | ||
|
||
File newFile = new File(canvasPath + magic + ".png"); | ||
File oldFile = new File(canvasPath + (magic - 1) + ".png"); | ||
|
||
FileOutputStream fos = new FileOutputStream(newFile); | ||
|
||
// wait for incoming file size | ||
long size = dis.readLong(); | ||
|
||
int bytes; | ||
byte[] buffer = new byte[4 * 1024]; | ||
while (size > 0 && (bytes = dis.read(buffer, 0, (int) Math.min(buffer.length, size))) != -1) { | ||
fos.write(buffer, 0, bytes); | ||
size -= bytes; | ||
} | ||
// Write all buffered bytes into the file | ||
fos.flush(); | ||
|
||
StdDraw.picture(width / 2, height / 2, canvasPath + magic + ".png"); | ||
magic = magic + 1; | ||
|
||
oldFile.delete(); | ||
StdDraw.show(); | ||
} | ||
} | ||
|
||
private static File join(File first, String... others) { | ||
return Paths.get(first.getPath(), others).toFile(); | ||
} | ||
|
||
|
||
public static void main(String[] args) throws IOException { | ||
System.out.println("BYOW Client. Please Enter the following information to connect to a server..."); | ||
Scanner scanner = new Scanner(System.in); | ||
System.out.print("IP Address: "); | ||
String ip = scanner.next(); | ||
System.out.print("Port (this must be a number): "); | ||
int port = scanner.nextInt(); | ||
|
||
BYOWClient client = new BYOWClient(); | ||
client.startConnection(ip, port); //ip port changes depending on link supplied by ngrok | ||
client.showCanvas(); | ||
char command; | ||
|
||
try { | ||
while (true) { | ||
if (StdDraw.hasNextKeyTyped()) { | ||
command = StdDraw.nextKeyTyped(); | ||
client.sendCommand(Character.toString(command)); | ||
} | ||
client.showCanvas(); | ||
StdDraw.clear(); | ||
if (client.shouldClose()) { | ||
client.stopConnection(); | ||
System.exit(0); | ||
} | ||
} | ||
} catch (java.net.SocketException e) { | ||
client.stopConnection(); | ||
System.out.println("Disconnected from server"); | ||
System.exit(0); | ||
} | ||
client.stopConnection(); | ||
System.out.println("Disconnected from server"); | ||
System.exit(0); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
package byow.Networking; | ||
|
||
import edu.princeton.cs.introcs.StdDraw; | ||
|
||
import java.io.*; | ||
import java.net.ServerSocket; | ||
import java.net.Socket; | ||
import java.nio.file.Paths; | ||
|
||
/** | ||
* Created by Arjun Sahai and Boren Tsai. | ||
*/ | ||
|
||
public class BYOWServer { | ||
|
||
static private final File CWD = new File(System.getProperty("user.dir")); | ||
static private final String CANVAS_FILE = ".server_canvas.png"; | ||
|
||
private ServerSocket serverSocket; | ||
private Socket clientStringSocket; | ||
private Socket clientWriteSocket; | ||
|
||
private BufferedReader in; | ||
private BufferedWriter out; | ||
private DataOutputStream dos; | ||
|
||
public BYOWServer(int port) throws IOException { | ||
serverSocket = new ServerSocket(port); | ||
System.out.println("Server started. Waiting for client to connect... "); | ||
clientWriteSocket = serverSocket.accept(); // block until client connects | ||
clientStringSocket = serverSocket.accept(); | ||
in = new BufferedReader(new InputStreamReader(clientStringSocket.getInputStream())); | ||
out = new BufferedWriter(new OutputStreamWriter(clientStringSocket.getOutputStream())); | ||
dos = new DataOutputStream(clientWriteSocket.getOutputStream()); | ||
System.out.println("Client connected!"); | ||
} | ||
|
||
public void sendCanvasConfig(int width, int height) { | ||
sendCanvas(width, height, true); | ||
} | ||
|
||
public void sendCanvas() { | ||
sendCanvas(0, 0, false); | ||
} | ||
|
||
/* | ||
This method will check to see if the client is sending a key press to the server | ||
This will not block your code | ||
*/ | ||
public boolean clientHasKeyTyped() { | ||
try { | ||
return in.ready(); | ||
} catch (IOException e) { | ||
stopConnection(); | ||
return false; | ||
} | ||
} | ||
|
||
/* | ||
Gives the next character sent from the client. | ||
If the client has not sent anything yet, then this method will block | ||
*/ | ||
public char clientNextKeyTyped() { | ||
try { | ||
return (char) in.read(); | ||
} catch (IOException e) { | ||
System.out.println("IO EXCEPTION CAUGHT"); | ||
stopConnection(); | ||
return 'q'; | ||
} | ||
} | ||
|
||
/* | ||
Closes all input/output streams and sockets. | ||
*/ | ||
public void stopConnection() { | ||
try { | ||
out.write("QUIT"); | ||
out.flush(); | ||
in.close(); | ||
dos.close(); | ||
clientStringSocket.close(); | ||
clientWriteSocket.close(); | ||
serverSocket.close(); | ||
} catch (IOException e) { | ||
return; | ||
} | ||
} | ||
|
||
/* | ||
Sends world bitmap and, optionally, StdDraw canvas configuration metadata. | ||
*/ | ||
private void sendCanvas(int width, int height, boolean sendConfig) { | ||
try { | ||
dos.writeBoolean(sendConfig); | ||
|
||
if (sendConfig) { | ||
dos.writeInt(width); | ||
dos.writeInt(height); | ||
dos.flush(); | ||
} else { | ||
dos.flush(); | ||
} | ||
|
||
|
||
// Save the canvas to a PNG file | ||
StdDraw.save(CANVAS_FILE); | ||
File canvas = join(CWD, CANVAS_FILE); | ||
|
||
// Send file size and unblock client from waiting | ||
dos.writeLong(canvas.length()); | ||
dos.flush(); | ||
|
||
FileInputStream fis = new FileInputStream(canvas); | ||
|
||
// break file into chunks and send to client | ||
int bytes; | ||
byte[] buffer = new byte[4 * 1024]; | ||
while ((bytes = fis.read(buffer)) != -1) { | ||
dos.write(buffer, 0, bytes); | ||
dos.flush(); | ||
} | ||
fis.close(); | ||
} catch (IOException e) { | ||
stopConnection(); | ||
} | ||
} | ||
|
||
private static File join(File first, String... others) { | ||
return Paths.get(first.getPath(), others).toFile(); | ||
} | ||
} |