Асинхронные сокеты

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by kurz, 19 Sep 2010.

  1. kurz

    kurz New Member

    Joined:
    5 Feb 2010
    Messages:
    32
    Likes Received:
    0
    Reputations:
    0
    Пишу на C# приложение, работающее с асинхронными сокетами. Смысл такой: есть 10 сокетов, подключенных к одному и тому же адресу, но забинденных (socket.Bind()) на 10 разных IPшников (на машине они имеются).
    В цикле хочу делать следующее:
    Code:
    while(true)
    {
                Send(socks[i], "Hello");
                sendDone.WaitOne(3000);
    
                Receive(socks[i]);
                receiveDone.WaitOne(3000);
                i++;
    }
    
    Вот остальные функции:

    Code:
    public class StateObject
    {
        public Socket workSocket = null;
        public const int BufferSize = 256;
        public byte[] buffer = new byte[BufferSize];
        public StringBuilder sb = new StringBuilder();
    }
    
    private static ManualResetEvent connectDone =
            new ManualResetEvent(false);
        private static ManualResetEvent sendDone =
            new ManualResetEvent(false);
        private static ManualResetEvent receiveDone =
            new ManualResetEvent(false);
    
    private static void ConnectCallback(IAsyncResult ar)
        {
            try
            {
                Socket client = (Socket)ar.AsyncState;
                client.EndConnect(ar);
                connectDone.Set();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }
    
        private static void Receive(Socket client)
        {
            try
            {
                receiveDone.Reset();
                Console.WriteLine("Receive");
                StateObject state = new StateObject();
                state.workSocket = client;
                client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                    new AsyncCallback(ReceiveCallback), state);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }
    
        private static void ReceiveCallback(IAsyncResult ar)
        {
            try
            {
                Console.WriteLine("ReceiveCallback");
                StateObject state = (StateObject)ar.AsyncState;
                Socket client = state.workSocket;
    
                int bytesRead = client.EndReceive(ar);
                if (bytesRead > 0)
                {
                    state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
                    client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                        new AsyncCallback(ReceiveCallback), state);
                }
                else
                {
                    if (state.sb.Length > 1)
                        response = state.sb.ToString();
                    receiveDone.Set();
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }
    
        private static void Send(Socket client, String data)
        {
            sendDone.Reset();
            Console.WriteLine("Send");
            byte[] byteData = Encoding.ASCII.GetBytes(data);
            client.BeginSend(byteData, 0, byteData.Length, 0,
                new AsyncCallback(SendCallback), client);
        }
    
        private static void SendCallback(IAsyncResult ar)
        {
            try
            {
                Console.WriteLine("SendCallback");
                Socket client = (Socket)ar.AsyncState;
                client.EndSend(ar);
                sendDone.Set();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }
    
    Первый прогон цикла проходит успешно (10 итераций). На второй заход он перестает получать ответ, а штампует ответ сокета №1 (socks[0]), примерно вывод такой:
    >response 1
    >response 2
    ...
    >response 10
    >response 10
    >response 10
    ... (10 раз)

    и на 21й:
    Error: An established connection was aborted by the software in your host machine

    В чем может быть проблема? Как вообще правильно использовать один и тот же асинхр. сокет для передачи-получения в цикле, не закрывая его?
     
    #1 kurz, 19 Sep 2010
    Last edited: 20 Sep 2010