Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/334.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# ReadAsync在异步TcpClient中仅读取一次_C# - Fatal编程技术网

C# ReadAsync在异步TcpClient中仅读取一次

C# ReadAsync在异步TcpClient中仅读取一次,c#,C#,我编写了一个简单的异步TcpClient。以下是守则的相关部分: public class AsyncTcpClient : IDisposable { private TcpClient tcpClient; private Stream stream; private int bufferSize = 8192; bool IsReceiving = false; public event EventHandler<string> On

我编写了一个简单的异步TcpClient。以下是守则的相关部分:

public class AsyncTcpClient : IDisposable
{
    private TcpClient tcpClient;
    private Stream stream;

    private int bufferSize = 8192;
    bool IsReceiving = false;

    public event EventHandler<string> OnDataReceived;
    public event EventHandler OnDisconnected;
    public event EventHandler OnConnected;
    public event EventHandler<Exception> OnError;

    public bool IsConnected
    {
        get
        {
            return tcpClient != null && tcpClient.Connected;
        }
    }

    public AsyncTcpClient() { }

    public async Task ConnectAsync(string host, int port, CancellationToken token = default(CancellationToken))
    {
        try
        {
            if (IsConnected) Close();
            tcpClient = new TcpClient();
            if (!tcpClient.ConnectAsync(host, port).Wait(250))
            {
                throw new TimeoutException();
            }
            stream = tcpClient.GetStream();
            OnConnected?.Invoke(this, EventArgs.Empty);
            await Receive();
        }
        catch (Exception)
        {
            OnDisconnected?.Invoke(this, EventArgs.Empty);
        }
    }

    public async Task Receive(CancellationToken token = default(CancellationToken))
    {
        try
        {
            if (!IsConnected || IsReceiving) throw new InvalidOperationException();
            IsReceiving = true;
            byte[] buffer = new byte[bufferSize];
            while (IsConnected)
            {
                token.ThrowIfCancellationRequested();

                // First time it reads the incoming data, then it hangs here forever
                int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length, token);
                if (bytesRead > 0)
                {
                    byte[] data = new byte[bytesRead];
                    Array.Copy(buffer, data, bytesRead);
                    OnDataReceived?.Invoke(this, Encoding.ASCII.GetString(data));
                }
                buffer = new byte[bufferSize];
            }
        }
        catch (ObjectDisposedException) { }
        catch (IOException)
        {
            throw;
        }
        finally
        {
            IsReceiving = false;
        }
    }
}
公共类AsyncTcpClient:IDisposable
{
私人TCP客户TCP客户;
私有流;
私有int bufferSize=8192;
bool IsReceiving=false;
已接收公共事件事件处理程序OnDataReceived;
公共事件事件处理程序未连接;
未连接的公共事件事件处理程序;
公共事件事件处理程序OnError;
公共图书馆断开了
{
收到
{
返回tcpClient!=null&&tcpClient.Connected;
}
}
公共异步TCPClient(){}
公共异步任务ConnectAsync(字符串主机,int端口,CancellationToken令牌=默认值(CancellationToken))
{
尝试
{
如果(断开连接)关闭();
tcpClient=新的tcpClient();
如果(!tcpClient.ConnectAsync(主机、端口).Wait(250))
{
抛出新的TimeoutException();
}
stream=tcpClient.GetStream();
OnConnected?.Invoke(此为EventArgs.Empty);
等待接收();
}
捕获(例外)
{
OnDisconnected?.Invoke(此为EventArgs.Empty);
}
}
公共异步任务接收(CancellationToken=默认值(CancellationToken))
{
尝试
{
如果(!IsConnected | | IsReceiving)抛出新的InvalidOperationException();
IsReceiving=真;
字节[]缓冲区=新字节[bufferSize];
while(断开连接)
{
token.ThrowIfCancellationRequested();
//它第一次读取传入的数据,然后永远挂在这里
int bytesRead=wait stream.ReadAsync(buffer,0,buffer.Length,token);
如果(字节读取>0)
{
字节[]数据=新字节[字节读取];
复制(缓冲区、数据、字节读取);
OnDataReceived?Invoke(这是Encoding.ASCII.GetString(数据));
}
buffer=新字节[bufferSize];
}
}
catch(ObjectDisposedException){}
捕获(IOException)
{
投
}
最后
{
IsReceiving=假;
}
}
}
在另一个应用程序上,我有一个等待连接的TcpListener。 成功连接后,服务器向客户端发送一些数据。从ReadAsync正确接收数据。然后,如果我尝试从服务器发送更多数据,客户端将在第二次调用ReadAsync时永远等待

我非常确定服务器正在工作,因为我收到了发送了正确字节的SendCallback

我是否错误地使用了ReadAsync

使现代化 我在这里添加我的服务器的完整的代码:

public class StateObject
{
    public Socket workSocket = null;
    public const int BufferSize = 4096;
    public byte[] buffer = new byte[BufferSize];
    public StringBuilder sb = new StringBuilder();
}

public class TcpServerAsync
{
    public readonly ConcurrentQueue<String> queue = new ConcurrentQueue<String>();
    public ManualResetEvent allDone = new ManualResetEvent(false);
    private Boolean _isRunning = true;

    public event EventHandler Connected;

    public TcpServerAsync(Int32 port)
    {
    }

    public void Start()
    {
        Thread t = new Thread(Run);
        t.Start();
    }

    public void Run()
    {
        IPHostEntry ipHostInfo = Dns.GetHostEntry("localhost");
        IPAddress ipAddress = ipHostInfo.AddressList[1];
        IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 5000);
        Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

        try
        {
            listener.Bind(localEndPoint);
            listener.Listen(1);

            while (_isRunning)
            {
                allDone.Reset();
                listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
                allDone.WaitOne();
            }
        }
        catch (Exception e)
        {
            Debug.WriteLine(e.ToString());
        }
    }

    public void AcceptCallback(IAsyncResult ar)
    {
        allDone.Set();

        Connected.Invoke(this, new EventArgs());
        Socket listener = (Socket)ar.AsyncState;
        Socket handler = listener.EndAccept(ar);

        StateObject state = new StateObject
        {
            workSocket = handler
        };
        handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);

        while (handler.Connected)
        {
            if (queue.TryDequeue(out String data))
            {
                try
                {
                    SendData(handler, data);
                }
                catch (Exception ex)
                {
                    throw;
                }
            }
            Thread.Sleep(0); 
        }
    }

    public void ReadCallback(IAsyncResult ar)
    {
        String content = String.Empty;

        StateObject state = (StateObject)ar.AsyncState;
        Socket handler = state.workSocket;

        int bytesRead = handler.EndReceive(ar);

        if (bytesRead > 0)
        {
            state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
            content = state.sb.ToString();
            Debug.WriteLine("Read {0} bytes from socket. \n Data : {1}", content.Length, content);
        }
    }

    public void SendData(Socket handler, String data)
    {
        byte[] byteData = Encoding.ASCII.GetBytes(data);
        handler.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), handler);
    }

    private void SendCallback(IAsyncResult ar)
    {
        try
        {
            Socket handler = (Socket)ar.AsyncState;

            int bytesSent = handler.EndSend(ar);
            Debug.WriteLine("Sent {0} bytes to client.", bytesSent);
        }
        catch (Exception e)
        {
            Debug.WriteLine(e.ToString());
        }
    }
}
公共类StateObject
{
公共套接字工作组=null;
public const int BufferSize=4096;
公共字节[]缓冲区=新字节[BufferSize];
公共StringBuilder sb=新StringBuilder();
}
公共类TcpServerAsync
{
public readonly ConcurrentQueue=new ConcurrentQueue();
public ManualResetEvent allDone=新的ManualResetEvent(false);
私有布尔值_isRunning=true;
公共事件事件处理程序已连接;
公共TcpServerAsync(Int32端口)
{
}
公开作废开始()
{
螺纹t=新螺纹(运行);
t、 Start();
}
公开募捐
{
IPHostEntry ipHostInfo=Dns.GetHostEntry(“本地主机”);
IPAddress IPAddress=ipHostInfo.AddressList[1];
IPEndPoint localEndPoint=新IPEndPoint(ipAddress,5000);
套接字侦听器=新套接字(AddressFamily.InterNetwork、SocketType.Stream、ProtocolType.Tcp);
尝试
{
Bind(localEndPoint);
听,听(1);
当(\u正在运行)
{
全部完成。重置();
beginacept(新的异步回调(AcceptCallback),listener);
全部完成。WaitOne();
}
}
捕获(例外e)
{
Debug.WriteLine(例如ToString());
}
}
公共无效接受回调(IAsyncResult ar)
{
allDone.Set();
调用(这个,新的EventArgs());
套接字侦听器=(套接字)ar.AsyncState;
套接字处理程序=listener.EndAccept(ar);
StateObject状态=新的StateObject
{
工作组=处理程序
};
BeginReceive(state.buffer,0,StateObject.BufferSize,0,新异步回调(ReadCallback),state);
while(handler.Connected)
{
if(queue.TryDequeue(输出字符串数据))
{
尝试
{
SendData(处理程序,数据);
}
捕获(例外情况除外)
{
投
}
}
睡眠(0);
}
}
公共void ReadCallback(IAsyncResult ar)
{
String content=String.Empty;
StateObject状态=(StateObject)ar.AsyncState;
套接字处理程序=state.workSocket;
int bytesRead=handler.EndReceive(ar);
如果(字节读取>0)
{
state.sb.Append(Encoding.ASCII.GetString(state.buffer,0,bytesRead));
content=state.sb.ToString();
WriteLine(“从套接字读取{0}字节。\n数据:{1}”,content.Length,content);
}
}
公共void SendData(套接字处理程序、字符串数据)
{
byte[]byteData=Encoding.ASCII.GetBytes(数据);
BeginSend(byteData,0,byteData.Length,0,新异步回调(SendCallback),handler);
}
私有void SendCallback(IAsyncResult ar)
{
尝试
{
套接字处理程序=(套接字)ar.AsyncState;
int bytesSent=handler.EndSend(ar);
WriteLine(“向客户端发送了{0}个字节。”,bytesSent);
}
抓住
    public void AcceptCallback(IAsyncResult ar)
    {
        allDone.Set();

        if (Connected != null)
        {
            Connected.Invoke(this, new EventArgs());
        }
        Socket listener = (Socket)ar.AsyncState;
        Socket handler = listener.EndAccept(ar);

        BeginReceive(handler);

        //while (handler.Connected)
        //{
        //    if (queue.TryDequeue(out String data))
        //    {
        //        try
        //        {
        //            SendData(handler, data);
        //        }
        //        catch (Exception ex)
        //        {
        //            throw;
        //        }
        //    }
        //    Thread.Sleep(0);
        //}
    }

    public void BeginReceive(Socket handler)
    {
        StateObject state = new StateObject
        {
            workSocket = handler
        };
        handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
    }

    public void ReadCallback(IAsyncResult ar)
    {
        String content = String.Empty;

        StateObject state = (StateObject)ar.AsyncState;
        Socket handler = state.workSocket;

        int bytesRead = handler.EndReceive(ar);

        if (bytesRead > 0)
        {
            state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
            content = state.sb.ToString();
            if (queue.TryDequeue(out String data))
            {
                try
                {
                    SendData(handler, data);
                }
                catch (Exception ex)
                {
                    throw;
                }
            }
            //SendData(handler, content);
            Debug.WriteLine("Read {0} bytes from socket. \n Data : {1}", content.Length, content);
        }
        BeginReceive(handler);
    }