2015-01-25 3 views
0

Я работаю над клиент-серверным приложением на C#, используя асинхронные сокеты. Как я слушаю для подключения, я получаю эту ошибкуC# async SocketException при привязке

необработанное исключение типа «System.Net.Sockets.SocketException» произошло в System.dll

Дополнительная информация: Только одно использование каждого сокета адрес (протокол/сетевой адрес/порт) обычно разрешается

Это линия, где это исключение происходит:

_listener.Bind(new IPEndPoint(0, port)); 

Код под Listener.Start(int port). В основной программе, вот как я называю метод:

void btnListen_Click(object sender, EventArgs e) 
     { 
      _listener = new Listener(); 
      _listener.Accepted += new Listener.SocketAcceptedHandler(listener_Accepted); 
      _listener.Start(8192); 
     } 

Я тестирование как приложения клиента и сервера в моем компьютере.

Это класс Listener.

namespace serverPC 
{ 
    class Listener 
    { 
     public delegate void SocketAcceptedHandler(Socket e); 
     public event SocketAcceptedHandler Accepted; 

     Socket _listener; 
     public int Port; 

     public bool Running 
     { 
      get; 
      private set; 
     } 

     public Listener() {Port = 0;} 

     public void Start(int port) 
     { 
      if (Running) 
       return; 

      _listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
      _listener.Bind(new IPEndPoint(0, port)); // This is where the SocketException error occurs 
      _listener.Listen(0); 

      _listener.BeginAccept(acceptedCallback, null); 
      Running = true; 
     } 

     public void Stop() 
     { 
      if (!Running) 
       return; 

      _listener.Close(); 
      Running = false; 
     } 

     void acceptedCallback(IAsyncResult ar) 
     { 
      try 
      { 
       Socket s = _listener.EndAccept(ar); 

       if (Accepted != null) 
       { 
        Accepted(s); 
       } 
      } 
      catch 
      { 

      } 

      if (Running) 
      { 
       try 
       { 
        _listener.BeginAccept(acceptedCallback, null); 
       } 
       catch 
       { 

       } 
      } 
     } 
    } 

} 

Вот Client класс.

namespace serverPC 
{ 
    struct ReceiveBuffer 
    { 
     public const int BUFFER_SIZE = 1024; 
     public byte[] Buffer; 
     public int ToReceive; 
     public MemoryStream BufStream; 

     public ReceiveBuffer(int toRec) 
     { 
      Buffer = new byte[BUFFER_SIZE]; 
      ToReceive = toRec; 
      BufStream = new MemoryStream(toRec); 
     } 

     public void Dispose() 
     { 
      Buffer = null; 
      ToReceive = 0; 
      Close(); 
      if (BufStream != null) 
       BufStream.Dispose(); 
     } 

     public void Close() 
     { 
      if (BufStream != null && BufStream.CanWrite) 
      { 
       BufStream.Close(); 
      } 
     } 
    } 

    class Client 
    { 
     byte[] lenBuffer; 
     ReceiveBuffer buffer; 
     Socket _socket; 

     public IPEndPoint EndPoint 
     { 
      get 
      { 
       if (_socket != null && _socket.Connected) 
       { 
        return (IPEndPoint)_socket.RemoteEndPoint; 
       } 

       return new IPEndPoint(IPAddress.None, 0); 
      } 
     } 

     public delegate void DisconnectedEventHandler(Client sender); 
     public event DisconnectedEventHandler Disconnected; 
     public delegate void DataReceivedEventHandler(Client sender, ReceiveBuffer e); 
     public event DataReceivedEventHandler DataReceived; 

     public Client(Socket s) 
     { 
      _socket = s; 
      lenBuffer = new byte[4]; 
     } 

     public void Close() 
     { 
      if (_socket != null) 
      { 
       _socket.Disconnect(false); 
       _socket.Close(); 
      } 

      buffer.Dispose(); 
      _socket = null; 
      lenBuffer = null; 
      Disconnected = null; 
      DataReceived = null; 
     } 

     public void ReceiveAsync() 
     { 
      _socket.BeginReceive(lenBuffer, 0, lenBuffer.Length, SocketFlags.None, receiveCallback, null); 
     } 

     void receiveCallback(IAsyncResult ar) 
     { 
      try 
      { 
       int rec = _socket.EndReceive(ar); 

       if (rec == 0) 
       { 
        if (Disconnected != null) 
        { 
         Disconnected(this); 
         return; 
        } 

        if (rec != 4) 
        { 
         throw new Exception(); 
        } 
       } 
      } 

      catch (SocketException se) 
      { 
       switch (se.SocketErrorCode) 
       { 
        case SocketError.ConnectionAborted: 
        case SocketError.ConnectionReset: 
         if (Disconnected != null) 
         { 
          Disconnected(this); 
          return; 
         } 
         break; 
       } 
      } 
      catch (ObjectDisposedException) 
      { 
       return; 
      } 
      catch (NullReferenceException) 
      { 
       return; 
      } 
      catch (Exception ex) 
      { 
       Console.WriteLine(ex.Message); 
       return; 
      } 

      buffer = new ReceiveBuffer(BitConverter.ToInt32(lenBuffer, 0)); 

      _socket.BeginReceive(buffer.Buffer, 0, buffer.Buffer.Length, SocketFlags.None, receivePacketCallback, null); 

     } 

     void receivePacketCallback(IAsyncResult ar) 
     { 
      int rec = _socket.EndReceive(ar); 

      if (rec <= 0) 
      { 
       return; 
      } 

      buffer.BufStream.Write(buffer.Buffer, 0, rec); 

      buffer.ToReceive -= rec; 

      if(buffer.ToReceive > 0) 
      { 
       Array.Clear(buffer.Buffer, 0, buffer.Buffer.Length); 

       _socket.BeginReceive(buffer.Buffer, 0, buffer.Buffer.Length, SocketFlags.None, receivePacketCallback, null); 
       return; 
      } 

      if (DataReceived != null) 
      { 
       buffer.BufStream.Position = 0; 
       DataReceived(this, buffer); 
      } 

      buffer.Dispose(); 

      ReceiveAsync(); 
     } 
    } 
} 

Почему возникает ошибка SocketException? Любая помощь приветствуется. Благодаря!

ответ

1

Итак, очевидные вещи для проверки - что-то уже прослушивает порт 8192, или есть еще одна причина, по которой ваша машина отклонит вашу программу, открыв этот порт (брандмауэры и т. Д.).

Другая проблема заключается в том, что вы дважды блокируете привязку с проверкой «Выполнение», вы делаете это только для экземпляра прослушивателя - нажатие кнопки создаст новый слушатель и попытается заставить его прослушивать порт 8192, который, поскольку у вас уже есть слушатель, связанный с ним, не будет с этим исключением.

+0

Нет проблем с первыми вещами, о которых вы упомянули. Мой брандмауэр позволяет мое приложение, и ничто другое не слушает порт (я проверил). Я не совсем понимаю, что вы здесь имеете в виду -> «вы блокируете привязку дважды с помощью« Running »check, вы делаете это только для экземпляра слушателя» – ellekaie

+0

Теперь я получаю то, что вы имеете в виду в последней части. – ellekaie

+0

Cool - все работает сейчас? – KirkSpaziani

Смежные вопросы