Здравствуйте, 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);
}
}
}