Правильно остановите асинхронное приложение TCP - PullRequest
3 голосов
/ 13 октября 2010

Привет, у меня в приложении SERVER есть событие нажатия кнопки разъединения, как показано ниже. До этого он будет оповещать других клиентов, отправляя команду "/ exit". После этого он отключит соединение.

 private void stopButton_Click(object sender, EventArgs e)
    {
        byte[] exit_command = Encoding.ASCII.GetBytes("/exit");
        g_server_conn.BeginSend(exit_command, 0, exit_command.Length, SocketFlags.None, new AsyncCallback(Send), g_server_conn);
        g_server_conn.Shutdown(SocketShutdown.Both);
        g_server_conn.Close();
    }

Проблема заключается в том, что сервер постоянно выполняет метод Socket.BeginRecieve ().Как нам сказать методу начала получения, чтобы он прекратил свою работу, чтобы я мог правильно закрыться.

private void Accept (IAsyncResult iar) {

        Socket winsock = (Socket)iar.AsyncState;
        g_server_conn = winsock.EndAccept(iar);


        //Function that exchanges names of each other
        NewClient(g_server_conn);

        Socket server_conn = g_server_conn;

        chat_msg = new byte[1024];
        server_conn.BeginReceive(chat_msg, 0, chat_msg.Length, SocketFlags.None, new AsyncCallback(Recieve), server_conn);

    }

    private void Recieve(IAsyncResult iar)
    {
        Socket server_conn = (Socket)iar.AsyncState;
        server_conn.EndReceive(iar);

        //If clients shutdown connection,Server recieves /exit command
        if (Encoding.ASCII.GetString(chat_msg, 0, chat_msg.Length) == "/exit")
        {
            g_server_conn.Shutdown(SocketShutdown.Both);
            g_server_conn.Close();
            return;
        }
        SetLabel(client_name, chatListBox);
        SetLabel(Encoding.ASCII.GetString(chat_msg), chatListBox);

        chat_msg = new byte[1024];
        server_conn.BeginReceive(chat_msg, 0, chat_msg.Length, SocketFlags.None, new AsyncCallback(Recieve), server_conn);


    }

Ответы [ 2 ]

0 голосов
/ 16 октября 2010

Должны ли клиенты действительно знать, почему сервер закрыл соединение (кажется, вы отправляете сообщение об отключении без информации о причинах, так или иначе)? Кажется, вы просто отправляете дополнительное сообщение клиентам, чтобы отключить их.

Вы можете просто отключить всех клиентов, и они получат сообщение о закрытии сокета, на стороне клиента будет показано, что соединение закрыто.

Кстати, нет смысла так часто преобразовывать полученную строку, конвертировать ее один раз из байтового массива в строку и все готово:).

Лично я бы сделал такой заказ:
1) Установите глобальный бул, чтобы мы больше не принимали новых клиентов (т. Е. Если новый клиент пытается подключиться в это время, я бы его не принял)
2) Перейдите к списку клиентов и отключите их
3) Закрой листер.

0 голосов
/ 13 октября 2010

Вы должны использовать IAsyncResult, возвращаемый методами BeginXXX.IIRC, вы можете распоряжаться WaitHandle.

...