C# 发送大量数据会断开服务器的连接
我正在建立一个网络库,用于进一步的项目,我知道一些网络(一般和编程),但当我想以高频传输较大的数据包时,仍然会遇到问题。在TCP中如何实现这一点? 一个可能的解决方案是chuncking,这根本不是问题,我将把它们放在一个缓冲区中,然后重新获得整个数据包。这会导致服务器的开销,处理大量数据会消耗大量资源。它会影响稳定性,因为服务器在某个地方卡住了,客户端在BeginSend(连接关闭)抛出ObjectDisposedException。当然,这可能是我的错,但是考虑一个“相对”的2048字节(2 kb)的小数据包,它在512字节(4块)中被分块:C# 发送大量数据会断开服务器的连接,c#,asyncsocket,C#,Asyncsocket,我正在建立一个网络库,用于进一步的项目,我知道一些网络(一般和编程),但当我想以高频传输较大的数据包时,仍然会遇到问题。在TCP中如何实现这一点? 一个可能的解决方案是chuncking,这根本不是问题,我将把它们放在一个缓冲区中,然后重新获得整个数据包。这会导致服务器的开销,处理大量数据会消耗大量资源。它会影响稳定性,因为服务器在某个地方卡住了,客户端在BeginSend(连接关闭)抛出ObjectDisposedException。当然,这可能是我的错,但是考虑一个“相对”的2048字节(2
//main.cs
静态void Main(字符串[]参数)
{
客户=新客户(“82.72.201.150”,2345);
client.sendpleted+=OnSend;
Console.WriteLine(client.Connect());
var字节=新字节[2048];
for(int i=0;i0)
发送(缓冲区,块*chunksize,rest);
}
//....
//client.cs
公共结构传输状态
{
公共字节[]缓冲区;
公共整数偏移;
公共整数计数;
处理公共事务;
公共手动重置事件等待句柄;
公共布尔等待;
}
公共无效发送(字节[]缓冲区,整数偏移量,整数计数)
{
var size=BitConverter.GetBytes(计数);
发送(大小,0,大小。长度,true);
发送(缓冲区、偏移量、计数、假);
}
私有无效发送(字节[]缓冲区,整数偏移量,整数计数,布尔等待,传输状态?状态=null)
{
状态=状态??新的传输状态
{
缓冲区=缓冲区,
偏移量=偏移量,
计数=计数,
已处理=0,
等等,
waitHandle=new ManualResetEvent(错误)
};
BeginSend(缓冲区、偏移量、计数、SocketFlags.None、SendCallback、状态);
如果(等待)
{
((TransferState)state.waitHandle.WaitOne();
}
}
私有无效发送(字节[]缓冲区,整数偏移量,整数计数,布尔等待,传输状态?状态=null)
{
状态=状态??新的传输状态
{
缓冲区=缓冲区,
偏移量=偏移量,
计数=计数,
已处理=0,
等等,
waitHandle=new ManualResetEvent(错误)
};
BeginSend(缓冲区、偏移量、计数、SocketFlags.None、SendCallback、状态);
如果(等待)
{
((TransferState)state.waitHandle.WaitOne();
}
}
私有void SendCallback(IAsyncResult结果)
{
if(result.AsyncState为TransferState==false)
抛出新ArgumentException(“无效的状态类型。”,“状态”);
var state=(TransferState)result.AsyncState;
var sent=socket.EndSend(结果);
state.handled+=已发送;
var-tosent=state.count-state.handled;
var offset=state.offset+state.handled;
如果(tosent>0)
{
发送(state.buffer、offset、tosent、state.wait、state);
}
其他的
{
state.waitHandle.Set();
SendCompleted(此,新的TransferCompletedArgs(此,状态));
}
}
//....
公共无效接收(传输状态?状态=空)
{
if(state==null)
{
var buffer=新字节[sizeof(int)];
socket.BeginReceive(buffer,0,sizeof(int),SocketFlags.None,ReceiveCallback,buffer);
}
其他的
{
var transferState=state.Value;
socket.BeginReceive(transferState.buffer、transferState.offset、transferState.count-transferState.handled、SocketFlags.None、ReceiveCallback、transferState);
}
}
私有void ReceiveCallback(IAsyncResult结果)
{
//收到要收到的金额
if(result.AsyncState为字节[])
{
var buffer=(字节[])result.AsyncState;
var rec=socket.EndReceive(结果);
if(rec!=4)//TODO:处理更正确
抛出新的NotImplementedException(“接收要接收的数量时出错”);
var toreceive=BitConverter.ToInt32(缓冲区,0);
var状态=新的TransferState
{
缓冲区=新字节[toreceive],
计数=接收,
等待=错误
};
接收(国家);
}
//知道我们知道我们能收到多少直到最后
else if(result.AsyncState为TransferState)
{
var state=(TransferState)result.AsyncState;
var rec=socket.EndReceive(结果);
state.offset+=rec;
state.handled+=rec;
var toreceive=state.count-state.handled;
如果(toreceive>0)
{
接收(国家);
Debug.WriteLine(“[{2}]大小不匹配:{0}/{1}”、state.handled、state.count、DateTime.Now.ToString(“mm:ss.fff”);
}
其他的
{
ReceiveCompleted(此,新的TransferCompletedArgs(此,状态));
接收();
}
}
其他的
{
抛出新ArgumentException(“状态不是byte[]或TransferState的类型”);
}
}
因此,如果很难理解:
//main.cs
static void Main(string[] args)
{
client = new Client("82.72.201.150", 2345);
client.SendCompleted += OnSend;
Console.WriteLine(client.Connect());
var bytes = new byte[2048];
for (int i = 0; i < bytes.Length; i++)
{
bytes[i] = (byte)((i*i + 0x25)%byte.MaxValue);
}
while (true)
{
SendChuncked(bytes);
Thread.Sleep(500);
}
}
static void SendChuncked(byte[] buffer, int chunksize = 512)
{
var chunks = buffer.Length/chunksize;
var rest = buffer.Length%chunksize;
var size = BitConverter.GetBytes(buffer.Length);
client.Send(size, 0, size.Length);
for (int i = 0; i < chunks; i++)
{
client.Send(buffer, i * chunksize, chunksize);
}
if (rest > 0)
client.Send(buffer, chunks * chunksize, rest);
}
//....
//client.cs
public struct TransferState
{
public byte[] buffer;
public int offset;
public int count;
public int handled;
public ManualResetEvent waitHandle;
public bool wait;
}
public void Send(byte[] buffer, int offset, int count)
{
var size = BitConverter.GetBytes(count);
Send(size, 0, size.Length, true);
Send(buffer, offset, count, false);
}
private void Send(byte[] buffer, int offset, int count, bool wait, TransferState? state = null)
{
state = state ?? new TransferState
{
buffer = buffer,
offset = offset,
count = count,
handled = 0,
wait = wait,
waitHandle = new ManualResetEvent(false)
};
socket.BeginSend(buffer, offset, count, SocketFlags.None, SendCallback, state);
if (wait)
{
((TransferState) state).waitHandle.WaitOne();
}
}
private void Send(byte[] buffer, int offset, int count, bool wait, TransferState? state = null)
{
state = state ?? new TransferState
{
buffer = buffer,
offset = offset,
count = count,
handled = 0,
wait = wait,
waitHandle = new ManualResetEvent(false)
};
socket.BeginSend(buffer, offset, count, SocketFlags.None, SendCallback, state);
if (wait)
{
((TransferState) state).waitHandle.WaitOne();
}
}
private void SendCallback(IAsyncResult result)
{
if (result.AsyncState is TransferState == false)
throw new ArgumentException("Invalid type of state.", "state");
var state = (TransferState)result.AsyncState;
var sent = socket.EndSend(result);
state.handled += sent;
var tosent = state.count - state.handled;
var offset = state.offset + state.handled;
if (tosent > 0)
{
Send(state.buffer, offset, tosent, state.wait, state);
}
else
{
state.waitHandle.Set();
SendCompleted(this, new TransferCompletedArgs(this, state));
}
}
//....
public void Receive(TransferState? state = null)
{
if (state == null)
{
var buffer = new byte[sizeof(int)];
socket.BeginReceive(buffer, 0, sizeof (int), SocketFlags.None, ReceiveCallback, buffer);
}
else
{
var transferState = state.Value;
socket.BeginReceive(transferState.buffer, transferState.offset, transferState.count - transferState.handled, SocketFlags.None, ReceiveCallback, transferState);
}
}
private void ReceiveCallback(IAsyncResult result)
{
//receiving the amount to receive
if (result.AsyncState is byte[])
{
var buffer = (byte[])result.AsyncState;
var rec = socket.EndReceive(result);
if (rec != 4) //TODO: HANDLE MORE PROPERLY
throw new NotImplementedException("Error while receiving the amoount to receive.");
var toreceive = BitConverter.ToInt32(buffer, 0);
var state = new TransferState
{
buffer = new byte[toreceive],
count = toreceive,
wait = false
};
Receive(state);
}
//know we know the amount we can receive it till the end
else if (result.AsyncState is TransferState)
{
var state = (TransferState)result.AsyncState;
var rec = socket.EndReceive(result);
state.offset += rec;
state.handled += rec;
var toreceive = state.count - state.handled;
if (toreceive > 0)
{
Receive(state);
Debug.WriteLine("[{2}] size mismatch: {0}/{1}", state.handled, state.count, DateTime.Now.ToString("mm:ss.fff"));
}
else
{
ReceiveCompleted(this, new TransferCompletedArgs(this, state));
Receive();
}
}
else
{
throw new ArgumentException("State is not typeof byte[] or TransferState.");
}
}