Skip to content

Commit

Permalink
Merge pull request #57 from Microsoft/TCPStringSpeedup
Browse files Browse the repository at this point in the history
Added logging; removed execrable string sending method.
  • Loading branch information
DaveyBiggers committed Jun 9, 2016
2 parents 8c0c47f + 0960ab2 commit 7c19d43
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 63 deletions.
155 changes: 92 additions & 63 deletions Minecraft/src/main/java/com/microsoft/Malmo/Utils/TCPSocketHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,17 @@
import java.util.Map.Entry;
import java.util.Random;
import java.util.UUID;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;

public class TCPSocketHelper
{
public static final int DEFAULT_SOCKET_TIMEOUT_MS = 100;
private static Logger logger = Logger.getLogger("com.microsoft.Malmo.TCPSocketHelper");
private static FileHandler filehandler = null;
private static boolean logging = false;

String address;
int port;
Expand All @@ -34,6 +41,30 @@ public TCPSocketHelper(String address, int port)
createSocket();
}

static void setLogging(boolean log)
{
logging = log;
if (log == true && filehandler == null)
{
try
{
filehandler = new FileHandler("TCPLog.txt");
filehandler.setFormatter(new SimpleFormatter());
}
catch (SecurityException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
logger.addHandler(filehandler);
}
}

public void close()
{
if (this.socket != null)
Expand Down Expand Up @@ -62,41 +93,15 @@ private void createSocket()
System.out.println("WARNING: Failed to create socket: " + e);
}
}

/** Send string over TCP.
* @param message string to be sent over TCP
* @param includeHeader if true, include a header indicating the length of the message
* @return true if message was successfully sent
*/
public boolean sendTCPString(String message, boolean includeHeader)
{
if (this.socket == null)
return false; // We have no socket, nothing is going to work.

boolean success = false;
try
{
DataOutputStream dos = new DataOutputStream(this.socket.getOutputStream());
if (includeHeader)
dos.writeInt(message.length());
dos.writeBytes(message);
success = true;
}
catch (IOException e)
{
System.out.println(String.format("Failed to send TCP message to %s:%d.", address, port));
System.out.println(e);
}
return success;
}

/** Send string over TCP to the specified address via the specified port, including a header.
* @param message string to be sent over TCP
* @return true if message was successfully sent
*/
public boolean sendTCPString(String message)
{
return sendTCPString(message, true);
byte[] bytes = message.getBytes();
return sendTCPBytes(bytes);
}

/** Send byte buffer over TCP, including a length header.
Expand All @@ -105,22 +110,35 @@ public boolean sendTCPString(String message)
*/
public boolean sendTCPBytes(byte[] buffer)
{
if (this.socket == null)
return false; // No socket, nothing will work.
if (this.socket == null)
return false; // No socket, nothing will work.

boolean success = false;
try
{
DataOutputStream dos = new DataOutputStream(this.socket.getOutputStream());
dos.writeInt(buffer.length);
dos.write(buffer, 0, buffer.length);
success = true;
}
catch (IOException e)
{
System.out.println(String.format("Failed to send TCP bytes to %s:%d.", this.address, this.port));
System.out.println(e);
}
boolean success = false;
try
{
DataOutputStream dos = new DataOutputStream(this.socket.getOutputStream());
if (logging)
{
long t1 = System.nanoTime();
dos.writeInt(buffer.length);
dos.write(buffer, 0, buffer.length);
dos.flush();
long t2 = System.nanoTime();
double rate = 1000.0 * 1000.0 * 1000.0 * (double)(buffer.length) / (1024.0 * (double)(t2 - t1));
logger.log(Level.INFO, "Sent " + buffer.length + " bytes to " + this.address + ":" + this.port + " at " + rate + " Kb/s");
}
else
{
dos.writeInt(buffer.length);
dos.write(buffer, 0, buffer.length);
}
success = true;
}
catch (IOException e)
{
System.out.println(String.format("Failed to send TCP bytes to %s:%d.", this.address, this.port));
System.out.println(e);
}
return success;
}

Expand Down Expand Up @@ -194,26 +212,37 @@ public void close()
* @param buffer the bytes to send
* @return true if the message was sent successfully
*/
public boolean sendTCPBytes(ByteBuffer buffer, int length)
{
boolean success = false;
try
{
ByteBuffer header = ByteBuffer.allocate(4).order(ByteOrder.BIG_ENDIAN).putInt(length);
header.flip();
ByteBuffer[] buffers = new ByteBuffer[2];
buffers[0] = header;
buffers[1] = buffer;
long bytesWritten = this.channel.write(buffers);
success = true;
}
catch (Exception e)
{
System.out.println(String.format("Failed to send TCP bytes to %s:%d.", this.address, this.port));
System.out.println(e);
}
return success;
}
public boolean sendTCPBytes(ByteBuffer buffer, int length)
{
boolean success = false;
try
{
ByteBuffer header = ByteBuffer.allocate(4).order(ByteOrder.BIG_ENDIAN).putInt(length);
header.flip();
ByteBuffer[] buffers = new ByteBuffer[2];
buffers[0] = header;
buffers[1] = buffer;
if (logging)
{
long t1 = System.nanoTime();
long bytesWritten = this.channel.write(buffers);
long t2 = System.nanoTime();
double rate = 1000.0 * 1000.0 * 1000.0 * (double)(bytesWritten) / (1024.0 * (double)(t2 - t1));
logger.log(Level.INFO, "Sent " + bytesWritten + " bytes to " + this.address + ":" + this.port + " at " + rate + " Kb/s");
}
else
{
this.channel.write(buffers);
}
success = true;
}
catch (Exception e)
{
System.out.println(String.format("Failed to send TCP bytes to %s:%d.", this.address, this.port));
System.out.println(e);
}
return success;
}
}

/** Simple utility class for providing and tracking tokens.<br>
Expand Down
2 changes: 2 additions & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
0.11.3?
-------------------
Fix: Issue 48 (Grid observer crippled by bad TCP string sending method).
Fix: Issue 52 (Malmo's internal Minecraft client/server messages limited to 64k data per message).
Fix: Issue 40 (added tostring() methods to Lua and Python classes).

0.11.2 (2016-06-06)
Expand Down

0 comments on commit 7c19d43

Please sign in to comment.