首页 > 解决方案 > 第二次通信的异步客户端/服务器c#问题

问题描述

我正在努力解决第一次成功与套接字完全连接后我可以建立第二个没有错误的问题。该怎么办 ?我已经给了这两个应用程序,因此您可以尝试帮助我解决该问题。非常感谢你们!

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Threading;
using System.Net;

namespace AsynchronousClientLearning
{
    class Program
    {
        public class ObjectState
        {
            public const int BufferSize = 256;
            public Socket wSocket { get; set; } = null;

            public byte[] Buffer = new byte[BufferSize];
            public StringBuilder sb = new StringBuilder();

        }

        public class AsyncSocketClient
        {
            private const int Port = 4343;
            private static ManualResetEvent connectComplete = new ManualResetEvent(false);
            private static ManualResetEvent sendCompleted = new ManualResetEvent(false);
            private static ManualResetEvent receiveCompleted = new ManualResetEvent(false);
            private static string  response = String.Empty;

            public static void StartClient()
            {

                try
                {
                    IPHostEntry ipHost = Dns.GetHostEntry(Dns.GetHostName());
                    IPAddress ip = ipHost.AddressList[0];
                    IPEndPoint remoteEndPoint = new IPEndPoint(ip, Port);

                    Socket client = new Socket(ip.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
                    client.BeginConnect(remoteEndPoint, new AsyncCallback(ConnectionCallback) , client);
                    Send(client, "this socket message<EOF>");
                    sendCompleted.WaitOne();

                    Receive(client);
                    receiveCompleted.WaitOne();
                    Console.WriteLine($"Response received {response}");
                    client.Shutdown(SocketShutdown.Both);
                    client.Close();
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                }

            }

            private static void Receive(Socket client)
            {

                try
                {
                    ObjectState state = new ObjectState();
                    state.wSocket = client;
                    client.BeginReceive(state.Buffer,0,ObjectState.BufferSize,0, new AsyncCallback(ReceiveCallback), state);


                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                }
            }

            private static void ReceiveCallback(IAsyncResult ar)
            {
                try
                {
                    ObjectState state = (ObjectState)ar.AsyncState;
                    var client = state.wSocket;
                    int byteRead = client.EndReceive(ar);
                    if(byteRead > 0)
                    {
                        state.sb.Append(Encoding.ASCII.GetString(state.Buffer, 0, byteRead));
                        client.BeginReceive(state.Buffer, 0, ObjectState.BufferSize, 0,
                            new AsyncCallback(ReceiveCallback), state);
                    }
                    else
                    {
                        if(state.sb.Length > 1)
                        {
                            response = state.sb.ToString();

                        }
                        receiveCompleted.Set();

                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                }
            }

            private static void Send(Socket client, string data)
            {
                byte[] byteData = Encoding.ASCII.GetBytes(data);
                client.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallBack), client);

            }

            private static void SendCallBack(IAsyncResult ar)
            {
                try
                {
                    Socket client = (Socket)ar.AsyncState;
                    int byteSent = client.EndSend(ar);
                    Console.WriteLine($"send: {byteSent} bytes to server");
                    sendCompleted.Set();
                    client.DisconnectAsync();
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                }
            }
        }

            private static void ConnectionCallback(IAsyncResult ar)
            {
                try
                {
                    Socket client = (Socket)ar.AsyncState;
                client.EndConnect(ar);
                Console.Write($"Socket connection : {client.RemoteEndPoint.ToString()}");

                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                }
            }
        
        static void Main(string[] args)
        {

            Console.WriteLine("Press any key to contine");

            Console.ReadLine();

            AsyncSocketClient.StartClient();
            Console.ReadLine();
        }
    }
}

应该关注 cca 10 客户端的服务器控制台应用程序,因此每个人的线程都不是解决方案

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Threading;
using System.Net;

namespace AsynchronousServerLearning
{
    class Program
    { public class ObjectState
        {
            public Socket wSocket = null;
            public const int bufferSize = 1024;
            public byte[] buffer = new byte[bufferSize];
            public StringBuilder sb = new StringBuilder();
        }
        public class AsyncSocketListener
        {
            public static ManualResetEvent allCompleted = new ManualResetEvent(false);

            public static void StartListener()
            {

                byte[] bytes = new byte[1024];

                IPHostEntry ipHost = Dns.GetHostEntry(Dns.GetHostName());
                IPAddress ip = ipHost.AddressList[0];
                IPEndPoint localEndPoint = new IPEndPoint(ip, 4343);
                Socket listener = new Socket(ip.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
                try
                {
                    listener.Bind(localEndPoint);
                    listener.Listen(100);
                    while(true)
                    {

                        allCompleted.Reset();
                        Console.WriteLine("waiting for incoming connections......");
                        listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
                        allCompleted.WaitOne();
                    }
                }
                catch(Exception e)
                {
                    Console.WriteLine(e.Message);
                }
                Console.WriteLine("Press enter to continue");
                Console.ReadLine();

            }

            private static void AcceptCallback(IAsyncResult ar)
            {
                allCompleted.Set();
                Socket listener = (Socket)ar.AsyncState;
                Socket handler = listener.EndAccept(ar);

                ObjectState state = new ObjectState();
                state.wSocket = handler;
                handler.BeginReceive(state.buffer, 0, ObjectState.bufferSize, 0,
                    new AsyncCallback(ReadCallback), state);
            }

            private static void ReadCallback(IAsyncResult ar)
            {
                string content = String.Empty;
                ObjectState state = (ObjectState)ar.AsyncState;
                Socket handler = state.wSocket;
                int bytesRead = handler.EndReceive(ar);
                if(bytesRead > 0)
                {

                    state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
                    content = state.sb.ToString();
                    if (content.IndexOf("<EOF>", StringComparison.Ordinal) > -1)
                    {
                        Console.WriteLine($"Read: {content.Length} bytes from \n socket Data: {content}");
                        Send(handler,content);
                    }
                    else
                    {
                        handler.BeginReceive(state.buffer, 0, ObjectState.bufferSize, 0,
                            new AsyncCallback(ReadCallback), state);

                    }

                }
            }

            private static void Send(Socket handler, string content)
            {
                byte[] byteData = Encoding.ASCII.GetBytes(content);
                handler.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), handler);
            }

            private static void SendCallback(IAsyncResult ar)
            {
                try
                {
                    Socket handler = (Socket)ar.AsyncState;
                    int byteSent = handler.EndSend(ar);
                    Console.WriteLine($"Sent {byteSent} to client");

                    handler.Shutdown(SocketShutdown.Both);
                    handler.Close();

                }
                catch( Exception e)
                {
                    Console.WriteLine(e);
                }
            }
        }
        static void Main(string[] args)
        {
            Console.WriteLine("Press any key to continue");
            Console.ReadLine();
            AsyncSocketListener.StartListener();
            Console.ReadLine();

        }
    }
}

从控制台登录:

Press any key to continue

Socket connection : [fe80::3d32:e16b:6438:ad43%8]:4343send: 24 bytes to server
Response received this socket message<EOF>

send: 24 bytes to server
Response received this socket message<EOF>
Socket connection : [fe80::3d32:e16b:6438:ad43%8]:4343System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'System.Net.Sockets.Socket'.
   at System.Net.Sockets.Socket.EndReceive(IAsyncResult asyncResult, SocketError& errorCode)
   at System.Net.Sockets.Socket.EndReceive(IAsyncResult asyncResult)
   at AsynchronousClientLearning.Program.AsyncSocketClient.ReceiveCallback(IAsyncResult ar) in C:\Users\Z660659\source\repos\AsynchronousClientLearning\AsynchronousClientLearning\Program.cs:line 82

...当我尝试时:

static void Main(string[] args)
{
    Console.WriteLine("Press any key to contine");

    Console.ReadLine();

    AsyncSocketClient.StartClient();
    Console.ReadLine();
    AsyncSocketClient.StartClient();
    Console.ReadLine();
}

标签: c#.netasynchronousserverthread-safety

解决方案


自从我挣扎以来,我一直在寻找 2 个小时的答案。现在我提出了解决错误的解决方案。通过重置 manualReserEvents。如果你发现更好的东西,请告诉我。

 private static void ReceiveCallback(IAsyncResult ar)
        {
            try
            {
                ObjectState state = (ObjectState)ar.AsyncState;
                var client = state.wSocket;
                int byteRead = client.EndReceive(ar);
                if(byteRead > 0)
                {
                    state.sb.Append(Encoding.ASCII.GetString(state.Buffer, 0, byteRead));
                    client.BeginReceive(state.Buffer, 0, ObjectState.BufferSize, 0,
                        new AsyncCallback(ReceiveCallback), state);
                }
                else
                {
                    if(state.sb.Length > 1)
                    {
                        response = state.sb.ToString();

                    }
                    receiveCompleted.Set();
                    connectComplete.Reset();
                    receiveCompleted.Reset();
                    sendCompleted.Reset();
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
        }

推荐阅读