One thing you could try is compress the messages yourselves via System.IO.Compression (see util below - you could just add as an extension).
But on the queueing/throttling question. Larger messages will always lag out a network more than smaller/optimized chunks. If you can break up data under 50k or less or use udp it may transmit faster with less queueing and validation than on tcp.
The absolute limitation on TCP packet size is 64K (65535 bytes), but in practicality this is far larger than the size of any packet you will see, because the lower layers (e.g. ethernet) have lower packet sizes.
The MTU (Maximum Transmission Unit) for Ethernet, for instance, is 1500 bytes. Some types of networks (like Token Ring) have larger MTUs, and some types have smaller MTUs, but the values are fixed for each physical technology.
from here: maximum packet size for a TCP connection
Things will go smoother when you break things up, multiplayer games have do to this and they also use udp more to limit extra validation (implementing reliable udp to validate individual messages and ordering when needed only).
CompressionUtil class, compress messages in and out before sending/after receive: https://gist.github.com/drawcode/8948293
public static class CompressUtil {
public static string ToCompressed(this string val) {
if (!IsStringCompressed(val)) {
return CompressString(val);
}
return val;
}
public static string ToDecompressed(this string val) {
if (IsStringCompressed(val)) {
return DecompressString(val);
}
return val;
}
public static string CompressString(string text) {
byte[] buffer = Encoding.UTF8.GetBytes(text);
var memoryStream = new MemoryStream();
using (var gZipStream = new GZipStream(memoryStream, CompressionMode.Compress, true)) {
gZipStream.Write(buffer, 0, buffer.Length);
}
memoryStream.Position = 0;
var compressedData = new byte[memoryStream.Length];
memoryStream.Read(compressedData, 0, compressedData.Length);
var gZipBuffer = new byte[compressedData.Length + 4];
Buffer.BlockCopy(compressedData, 0, gZipBuffer, 4, compressedData.Length);
Buffer.BlockCopy(BitConverter.GetBytes(buffer.Length), 0, gZipBuffer, 0, 4);
return Convert.ToBase64String(gZipBuffer);
}
public static string DecompressString(string compressedText) {
byte[] gZipBuffer = Convert.FromBase64String(compressedText);
using (var memoryStream = new MemoryStream()) {
int dataLength = BitConverter.ToInt32(gZipBuffer, 0);
memoryStream.Write(gZipBuffer, 4, gZipBuffer.Length - 4);
var buffer = new byte[dataLength];
memoryStream.Position = 0;
using (var gZipStream = new GZipStream(memoryStream, CompressionMode.Decompress)) {
gZipStream.Read(buffer, 0, buffer.Length);
}
return Encoding.UTF8.GetString(buffer);
}
}
public static bool IsStringCompressed(string data) {
if (IsStringCompressedGZip(data) || IsStringCompressedPKZip(data)) {
return true;
}
return false;
}
public static bool IsStringCompressedGZip(string data) {
return CheckSignatureString(data, 3, "1F-8B-08");
}
public static bool IsStringCompressedPKZip(string data) {
return CheckSignatureString(data, 4, "50-4B-03-04");
}
public static bool CheckSignatureFile(string filepath, int signatureSize, string expectedSignature) {
if (String.IsNullOrEmpty(filepath))
throw new ArgumentException("Must specify a filepath");
if (String.IsNullOrEmpty(expectedSignature))
throw new ArgumentException("Must specify a value for the expected file signature");
using (FileStream fs = new FileStream(filepath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) {
if (fs.Length < signatureSize)
return false;
byte[] signature = new byte[signatureSize];
int bytesRequired = signatureSize;
int index = 0;
while (bytesRequired > 0) {
int bytesRead = fs.Read(signature, index, bytesRequired);
bytesRequired -= bytesRead;
index += bytesRead;
}
string actualSignature = BitConverter.ToString(signature);
if (actualSignature == expectedSignature)
return true;
else
return false;
}
}
public static bool CheckSignatureString(string data, int signatureSize, string expectedSignature) {
byte[] datas = Encoding.ASCII.GetBytes(data);
using (MemoryStream ms = new MemoryStream(datas)) {
if (ms.Length < signatureSize)
return false;
byte[] signature = new byte[signatureSize];
int bytesRequired = signatureSize;
int index = 0;
while (bytesRequired > 0) {
int bytesRead = ms.Read(signature, index, bytesRequired);
bytesRequired -= bytesRead;
index += bytesRead;
}
string actualSignature = BitConverter.ToString(signature);
if (actualSignature == expectedSignature)
return true;
else
return false;
}
}
}