none
Несколько вопросов по асинхронным сокетам. RRS feed

  • Общие обсуждения

  • Всем доброго времени суток!
    При написание клиент-серверной системы накопилось некоторое кол-во вопросов:

    1. Есть сервер, у него есть метод Start(), который запускается в начале работы серверной части. Если в процессе работы клиент вызовет метод Disconnetc() или Close(), то сервер перестанет принимать подключения. Собственно вопрос: [b]есть ли какие-то встроенные механизмы для "перезапуска" BeginAccept?[/b] (чтобы не писать это на коленке с помощью бесконечного while, WaitOne или собственной "очереди-массива" соединений)

           public void Start()
    {
    SocketOfListner.Bind(remoteIEP);
    SocketOfListner.Listen((int)SocketOptionName.MaxConnections);
    SocketOfListner.BeginAccept(new AsyncCallback(OnAccept), null);
    }
    2. Если вызвать методы BeginSend и BeginReceive без Thread.Sleep(n), то он отправит, не приняв. [b]Как дождаться окончания принятия\отправления данных?[/b]

               SocOfSend.BeginSend(BDataSend, 0, BDataSend.Length, SocketFlags.None, new AsyncCallback(OnSend), SocOfSend);
    SocOfSend.BeginReceive(BDataReceive, 0, BDataReceive.Length, SocketFlags.None, new AsyncCallback(OnReceive), SocOfSend);
    3. Собственно, что должно писаться в методах OnSend и OnReceive? (которые вызываются в BeginSend\BeginReceive) Там хватает примерно следующего:

               var clientSocket = (Socket) ar.AsyncState;
    //clientSocket.EndReceive(ar);
               var client = (Socket)ar.AsyncState;
    //client.EndSend(ar);
    Если раскоментить EndSend(ar) и EndReceive(ar), то будут разрывать соединение, не успев принять\передать. Может быть тут и нужно писать ожидание завершения приема\передачи?

    Буду рад любой помощи! Заранее спасибо! =)
    • Изменен тип I.Vorontsov 27 октября 2009 г. 11:27
    • Перемещено Siddharth Chavan 1 октября 2010 г. 21:56 MSDN Forums Consolidation (От:Visual C#)
    2 октября 2009 г. 1:22

Все ответы

  • Добрый день.

    Возможно, информация ниже вам поможет

    Для асинхронной работы с сокетами я не использую методы BeginXXX и EndXXX, а использую XXXAsync.

    Чтобы не писать бесконечного цикла я использую сл. код.

    	public class ConnectionListener
    	{
    		private Socket _listenerSocket;
    		private SocketAsyncEventArgs _sockEvtArgs;
    		private ServerConnectionManager _connectionManager = new ServerConnectionManager();
    
    		public Socket ListenerSocket
    		{
    			get { return _listenerSocket; }
    			set { _listenerSocket = value; }
    		}
    
    		public void Run(int port)
    		{
    			try
    			{
    				IPEndPoint listenerEndPoint = new IPEndPoint(IPAddress.Any, port);
    				_listenerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    				_listenerSocket.Bind(listenerEndPoint);
    				_listenerSocket.Listen(20);
    #if DEBUG
    				Console.WriteLine("Waiting for incoming connections");
    #endif
    				AcceptIncoming();
    			}
    			catch (Exception ex)
    			{
    				Logger.AddToLog("Listen Connections", ex.ToString());
    			}
    		}
    
    		private void AcceptIncoming()
    		{
    			_sockEvtArgs = new SocketAsyncEventArgs(){UserToken = _connectionManager};
    			_sockEvtArgs.Completed += new EventHandler<SocketAsyncEventArgs>(AcceptConnectionComplieted);
    			bool isOperationAsynchronous = _listenerSocket.AcceptAsync(_sockEvtArgs);
    			if (!isOperationAsynchronous)
    			{
    				ProcessAccept(_sockEvtArgs);
    			}
    		}
    
    		private void AcceptConnectionComplieted(object sender, SocketAsyncEventArgs e)
    		{
    			ProcessAccept(e);
    		}
    
    		private void ProcessAccept(SocketAsyncEventArgs e)
    		{
    #if DEBUG
    			Console.WriteLine("Accepted Connection...");
    #endif
    			_connectionManager.Manage(e.AcceptSocket);
    			AcceptIncoming();
    		}

    Аналогично использую ReceiveAsync и SendAsync.

    6 октября 2009 г. 19:59