Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typo3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 发送大量数据会断开服务器的连接_C#_Asyncsocket - Fatal编程技术网

C# 发送大量数据会断开服务器的连接

C# 发送大量数据会断开服务器的连接,c#,asyncsocket,C#,Asyncsocket,我正在建立一个网络库,用于进一步的项目,我知道一些网络(一般和编程),但当我想以高频传输较大的数据包时,仍然会遇到问题。在TCP中如何实现这一点? 一个可能的解决方案是chuncking,这根本不是问题,我将把它们放在一个缓冲区中,然后重新获得整个数据包。这会导致服务器的开销,处理大量数据会消耗大量资源。它会影响稳定性,因为服务器在某个地方卡住了,客户端在BeginSend(连接关闭)抛出ObjectDisposedException。当然,这可能是我的错,但是考虑一个“相对”的2048字节(2

我正在建立一个网络库,用于进一步的项目,我知道一些网络(一般和编程),但当我想以高频传输较大的数据包时,仍然会遇到问题。在TCP中如何实现这一点? 一个可能的解决方案是chuncking,这根本不是问题,我将把它们放在一个缓冲区中,然后重新获得整个数据包。这会导致服务器的开销,处理大量数据会消耗大量资源。它会影响稳定性,因为服务器在某个地方卡住了,客户端在BeginSend(连接关闭)抛出ObjectDisposedException。当然,这可能是我的错,但是考虑一个“相对”的2048字节(2 kb)的小数据包,它在512字节(4块)中被分块:

//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.");
        }
    }