private static void SendRecv_Stream_TCP(IPAddress listenAt, bool useMultipleBuffers)
{
const int BytesToSend = 123456;
const int ListenBacklog = 1;
const int LingerTime = 10;
const int TestTimeout = 30000;
var server = new Socket(listenAt.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
server.BindToAnonymousPort(listenAt);
server.Listen(ListenBacklog);
int bytesReceived = 0;
var receivedChecksum = new Fletcher32();
var serverThread = new Thread(() =>
{
using (server)
{
Socket remote = server.Accept();
Assert.NotNull(remote);
using (remote)
{
if (!useMultipleBuffers)
{
var recvBuffer = new byte[256];
for (;;)
{
int received = remote.Receive(recvBuffer, 0, recvBuffer.Length, SocketFlags.None);
if (received == 0)
{
break;
}
bytesReceived += received;
receivedChecksum.Add(recvBuffer, 0, received);
}
}
else
{
var recvBuffers = new List<ArraySegment<byte>> {
new ArraySegment<byte>(new byte[123]),
new ArraySegment<byte>(new byte[256], 2, 100),
new ArraySegment<byte>(new byte[1], 0, 0),
new ArraySegment<byte>(new byte[64], 9, 33)
};
for (;;)
{
int received = remote.Receive(recvBuffers, SocketFlags.None);
if (received == 0)
{
break;
}
bytesReceived += received;
for (int i = 0, remaining = received; i < recvBuffers.Count && remaining > 0; i++)
{
ArraySegment<byte> buffer = recvBuffers[i];
int toAdd = Math.Min(buffer.Count, remaining);
receivedChecksum.Add(buffer.Array, buffer.Offset, toAdd);
remaining -= toAdd;
}
}
}
}
}
});
serverThread.Start();
EndPoint clientEndpoint = server.LocalEndPoint;
var client = new Socket(clientEndpoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
client.Connect(clientEndpoint);
int bytesSent = 0;
var sentChecksum = new Fletcher32();
using (client)
{
var random = new Random();
if (!useMultipleBuffers)
{
var sendBuffer = new byte[512];
for (int sent = 0, remaining = BytesToSend; remaining > 0; remaining -= sent)
{
random.NextBytes(sendBuffer);
sent = client.Send(sendBuffer, 0, Math.Min(sendBuffer.Length, remaining), SocketFlags.None);
bytesSent += sent;
sentChecksum.Add(sendBuffer, 0, sent);
}
}
else
{
var sendBuffers = new List<ArraySegment<byte>> {
new ArraySegment<byte>(new byte[23]),
new ArraySegment<byte>(new byte[256], 2, 100),
new ArraySegment<byte>(new byte[1], 0, 0),
new ArraySegment<byte>(new byte[64], 9, 9)
};
for (int sent = 0, toSend = BytesToSend; toSend > 0; toSend -= sent)
{
for (int i = 0; i < sendBuffers.Count; i++)
{
random.NextBytes(sendBuffers[i].Array);
}
sent = client.Send(sendBuffers, SocketFlags.None);
bytesSent += sent;
for (int i = 0, remaining = sent; i < sendBuffers.Count && remaining > 0; i++)
{
ArraySegment<byte> buffer = sendBuffers[i];
int toAdd = Math.Min(buffer.Count, remaining);
sentChecksum.Add(buffer.Array, buffer.Offset, toAdd);
remaining -= toAdd;
}
}
}
client.LingerState = new LingerOption(true, LingerTime);
}
Assert.True(serverThread.Join(TestTimeout), "Completed within allowed time");
Assert.Equal(bytesSent, bytesReceived);
Assert.Equal(sentChecksum.Sum, receivedChecksum.Sum);
}