Я работаю над клиент-серверным приложением на C#, и мне нужно заставить работать асинхронные сокеты, чтобы я мог обрабатывать сразу несколько соединений. Технически это работает так, как сейчас, но я получаю OutOfMemoryException
примерно через 3 минуты работы. MSDN говорит, чтобы использовать WaitHandler
, чтобы сделать WaitOne()
после socket.BeginAccept()
, но это на самом деле не позволяет мне это делать. Когда я пытаюсь сделать это в коде, он говорит, что WaitHandler
- абстрактный класс или интерфейс, и я не могу его создать. Я подумал, что, возможно, Id попробует статическую ссылку, но у нее нет метода WaitOne()
, только WaitAll()
и WaitAny()
. Основная проблема заключается в том, что в документах он не дает полного фрагмента кода, поэтому вы не можете увидеть, что происходит с их обработчиком ожидания. его просто переменная, называемая allDone
, которая также имеет метод Reset()
в фрагменте, которого нет у waithandler.C# Asynchronous Network IO и OutOfMemoryException
После того, как в своих документах выкопались, я нашел связанную вещь о AutoResetEvent
в пространстве имен Threading
. Он имеет WaitOne()
и метод Reset()
. Поэтому я попробовал это около while(true) { ... socket.BeginAccept(...); ... }
. К сожалению, это заставляет использовать только одно соединение за раз. Поэтому я не совсем уверен, куда идти. Вот мой код:
class ServerRunner
{
private Byte[] data = new Byte[2048];
private int size = 2048;
private Socket server;
static AutoResetEvent allDone = new AutoResetEvent(false);
public ServerRunner()
{
server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint iep = new IPEndPoint(IPAddress.Any, 33333);
server.Bind(iep);
Console.WriteLine("Server initialized..");
}
public void Run()
{
server.Listen(100);
Console.WriteLine("Listening...");
while (true)
{
//allDone.Reset();
server.BeginAccept(new AsyncCallback(AcceptCon), server);
//allDone.WaitOne();
}
}
void AcceptCon(IAsyncResult iar)
{
Socket oldserver = (Socket)iar.AsyncState;
Socket client = oldserver.EndAccept(iar);
Console.WriteLine(client.RemoteEndPoint.ToString() + " connected");
byte[] message = Encoding.ASCII.GetBytes("Welcome");
client.BeginSend(message, 0, message.Length, SocketFlags.None, new AsyncCallback(SendData), client);
}
void SendData(IAsyncResult iar)
{
Socket client = (Socket)iar.AsyncState;
int sent = client.EndSend(iar);
client.BeginReceive(data, 0, size, SocketFlags.None, new AsyncCallback(ReceiveData), client);
}
void ReceiveData(IAsyncResult iar)
{
Socket client = (Socket)iar.AsyncState;
int recv = client.EndReceive(iar);
if (recv == 0)
{
client.Close();
server.BeginAccept(new AsyncCallback(AcceptCon), server);
return;
}
string receivedData = Encoding.ASCII.GetString(data, 0, recv);
//process received data here
byte[] message2 = Encoding.ASCII.GetBytes("reply");
client.BeginSend(message2, 0, message2.Length, SocketFlags.None, new AsyncCallback(SendData), client);
}
}