Асинхронные сокеты .NET
От: AndrewKarmanov  
Дата: 29.09.07 08:11
Оценка:
Здравствуйте, я начинающий c#-программист, поэтому не судите слишком сурово).
Возникла задача написания асинхронного сервера. Листинг, который я нашел,
довольно популярен, и уверен на 100%-рабочий:
....
Сама программка (в теле главной функции) выглядит так:
AsynchronousIoServer srv=new AsynchronousIoServer(11000);
srv.Start();
....
После компилляции в диспетчере задач загрузка процессора минимальная.
Далее, через telnet отправляю данные на прослушиваемый порт (1 байт),
данные приходят, и загрузка процессора тут же становится 100%. И так
и держится. Ниже привожу код класса сервера. Заранее признателен, если
укажете на мою ошибку.

class AsynchronousIoServer
{
private Socket _serverSocket;
private int _port;

public AsynchronousIoServer(int port) { _port = port; }

private class ConnectionInfo
{
public Socket Socket;
public byte[] Buffer;
}

private List<ConnectionInfo> _connections =
new List<ConnectionInfo>();

private void SetupServerSocket()
{
// Получаем информацию о локальном компьютере
IPHostEntry localMachineInfo =
Dns.GetHostEntry(Dns.GetHostName());
IPEndPoint myEndpoint = new IPEndPoint(
localMachineInfo.AddressList[0], _port);

// Создаем сокет, привязываем его к адресу
// и начинаем прослушивание
_serverSocket = new Socket(
myEndpoint.Address.AddressFamily,
SocketType.Stream, ProtocolType.Tcp);
_serverSocket.Bind(myEndpoint);
_serverSocket.Listen((int)
SocketOptionName.MaxConnections);
}
public void Start()
{
SetupServerSocket();
for (int i = 0; i < 10; i++)
_serverSocket.BeginAccept(new
AsyncCallback(AcceptCallback), _serverSocket);
}

private void AcceptCallback(IAsyncResult result)
{
ConnectionInfo connection = new ConnectionInfo();
try
{
// Завершение операции Accept
Socket s = (Socket)result.AsyncState;
connection.Socket = s.EndAccept(result);
connection.Buffer = new byte[255];
lock (_connections) _connections.Add(connection);

// Начало операции Receive и новой операции Accept
connection.Socket.BeginReceive(connection.Buffer,
0, connection.Buffer.Length, SocketFlags.None,
new AsyncCallback(ReceiveCallback),
connection);
_serverSocket.BeginAccept(new AsyncCallback(
AcceptCallback), result.AsyncState);
}
catch (SocketException exc)
{
CloseConnection(connection);
Console.WriteLine("Socket exception: " +
exc.SocketErrorCode);
}
catch (Exception exc)
{
CloseConnection(connection);
Console.WriteLine("Exception: " + exc);
}
}

private void ReceiveCallback(IAsyncResult result)
{
ConnectionInfo connection =
(ConnectionInfo)result.AsyncState;
try
{
int bytesRead =
connection.Socket.EndReceive(result);
if (0 != bytesRead)
{
lock (_connections)
{
foreach (ConnectionInfo conn in
_connections)
{
if (connection != conn)
{
conn.Socket.Send(connection.Buffer,
bytesRead, SocketFlags.None);
}
}
}
connection.Socket.BeginReceive(
connection.Buffer, 0,
connection.Buffer.Length, SocketFlags.None,
new AsyncCallback(ReceiveCallback),
connection);
}
else CloseConnection(connection);
}
catch (SocketException exc)
{
CloseConnection(connection);
Console.WriteLine("Socket exception: " +
exc.SocketErrorCode);
}
catch (Exception exc)
{
CloseConnection(connection);
Console.WriteLine("Exception: " + exc);
}
}

private void CloseConnection(ConnectionInfo ci)
{
ci.Socket.Close();
lock (_connections) _connections.Remove(ci);
}
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.