Re: Socket + Отключение клиента
От: Jolly Roger  
Дата: 21.03.10 04:36
Оценка: 2 (1)
Здравствуйте, EyfelFenk, Вы писали:

EF>не ругайте сильно.


А несильно можно?

EF>Вся проблема в том, что DoAcceptTcpClientCallback срабатывает только один раз =( А как перехватить момент подключение к серверу и момент отключения от сервера?


Чтобы сработало больше одного раза, надо вызвать больше одного раза А чтобы "поймать" момент отключения клиента, сокет должен находиться в состоянии передачи или приёма.

Да вот Вам упрощённый пример эхо-сервера, как раз вчера набросал для теста.

using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace SrvTcpListener
{
    class ServerProgram
    {
        class AsyncData
        {
            public Socket s;
            public byte[] Buf;
        }

        static volatile bool _сlose;

        static AsyncCallback acptCallback = new AsyncCallback((ar) =>
            {
                var listener = (TcpListener)ar.AsyncState;
                if (_сlose) return;
                listener.BeginAcceptSocket(acptCallback, listener);

                var socket = listener.EndAcceptSocket(ar);
                AsyncData data = new AsyncData();
                data.s = socket;
                data.Buf = new byte[256];
                socket.BeginReceive(data.Buf, 0, data.Buf.Length,
                    SocketFlags.None, recvCallback, data);
            });

        static AsyncCallback recvCallback = new AsyncCallback((ar) =>
            {
                SocketError err;
                AsyncData data = (AsyncData)ar.AsyncState;
                int Len = data.s.EndReceive(ar, out err);
                if (Len > 0 && err == SocketError.Success)
                {
                    data.s.BeginSend(data.Buf, 0, Len, SocketFlags.None, (ar2) =>
                        {
                            SocketError err2;
                            int Len2 = data.s.EndSend(ar2, out err2);
                            if (Len2 > 0 && err2 == SocketError.Success)
                                data.s.BeginReceive(data.Buf, 0, data.Buf.Length,
                                    SocketFlags.None, recvCallback, data);
                            else
                                // Клиент потерян
                                data.s.Close();
                        }, null);
                }
                else
                    // Клиент потерян
                    data.s.Close();
            });
        static void Main(string[] args)
        {
            IPAddress addr = IPAddress.Parse("127.0.0.1");
            var listener = new TcpListener(addr, 7777);
            _сlose = false;
            listener.Start();
            listener.BeginAcceptSocket(acptCallback, listener);
            Console.WriteLine("Start");
            Console.ReadKey();
            _сlose = true;
            listener.Stop();
            Console.WriteLine("Stop");
            Thread.Sleep(1);
        }
    }
}
"Нормальные герои всегда идут в обход!"
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.