2017-04-20 10 views
0


J'ai un problème avec les sockets dans mon programme. Je développe un serveur FTP intégré dans un autre programme et pour ce faire j'ai créé un socket et un TCPListener. Mon problème se produit dans ce cas:
- J'ouvre la connexion pour la première fois, si personne ne se connecte et je le ferme, tout va bien; sinon, si quelqu'un se connecte à mon serveur FTP tout fonctionne bien aussi;
- Si, après avoir fermé la connexion la première fois et l'avoir ouvert de nouveau sans que personne n'ait été connecté auparavant, j'obtiens une SocketException de "socket/ip address/port" déjà utilisée et je ne peux plus l'instancier.
Le code de ma fonction est que:Délai de réception dans Compact Framework 2.0

public void Start() 
    { 
     ServerStarted = true; 

     if (this.authHandler == null) 
      this.authHandler = new DefaultAuthHandler(); 

     if (this.fsHandler == null) 
      this.fsHandler = new DefaultFileSystemHandler(); 

     Socket socketServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 

     TcpListener listenerServer = new TcpListener(endpoint); 
     listenerServer.Start(); // The exception is here at the second time 
           // I open the connection without anybody connected before 

     try 
     { 
      while (ServerStarted) 
      { 
       socketServer = listenerServer.AcceptSocket(); 

       try 
       { 
        IPEndPoint socketPort = (IPEndPoint)socketServer.RemoteEndPoint; 
        Session session = new Session(socketServer, bufferSize, this.authHandler.Clone(socketPort), this.fsHandler.Clone(socketPort)); 

        session.Start(); 
        sessions.Add(session); 

        p_HostIPAddress = socketPort.Address; 

        if (p_HostIPAddress != null) 
         HostConnected = true; 

        // Purge old sessions 
        for (int i = sessions.Count - 1; i >= 0; --i) 
        { 
         if (!sessions[i].IsOpen) 
         { 
          sessions.RemoveAt(i); 
          --i; 
         } 
        } 
       } 
       catch(Exception ex) 
       { 
       } 
      } 
     } 
     catch (SocketException socketEx) 
     { 
     } 
     finally 
     { 
      foreach (Session s in sessions) 
      { 
       s.Stop(); 
       HostConnected = false; 
      } 
      TcpSocketListener = null; 
     } 
    } 

Je sais que dans le cadre compact il n'y a pas les appels du délai d'attente et donc, que puis-je faire pour éviter que mon socket reste ouverte en arrière-plan. ohw, à droite, une autre info:
mon serveur ftp réellement utiliser la bibliothèque OpenNETCF FTP

Répondre

0

Ok, je l'ai résolu en utilisant la SetSocketOption et j'ai changé un peu le code. Voici maintenant:

public void Start() 
    { 
     ServerStarted = true; 

     if (this.authHandler == null) 
      this.authHandler = new DefaultAuthHandler(); 

     if (this.fsHandler == null) 
      this.fsHandler = new DefaultFileSystemHandler(); 

     socketServer = new Socket(AddressFamily.InterNetwork, 
            SocketType.Stream, 
            ProtocolType.Tcp); 

     /* Here is the change. In this way I can reuse multiple times the 
     * same address without getting the SocketException.*/ 
     socketServer.SetSocketOption(SocketOptionLevel.Socket, 
            SocketOptionName.ReuseAddress, 
            1); 

     Socket handler = null; 

     try 
     { 
      socketServer.Bind(endpoint); 
      socketServer.Listen(10); 

      while (ServerStarted) 
      { 
       handler = socketServer.Accept(); 

       try 
       { 
        IPEndPoint socketPort = (IPEndPoint)handler.RemoteEndPoint; 
        Session session = new Session(handler,bufferSize, 
             this.authHandler.Clone(socketPort), 
             this.fsHandler.Clone(socketPort)); 

        session.Start(); 
        sessions.Add(session); 

        p_HostIPAddress = socketPort.Address; 

        if (p_HostIPAddress != null) 
         HostConnected = true; 

        // Purge old sessions 
        for (int i = sessions.Count - 1; i >= 0; --i) 
        { 
         if (!sessions[i].IsOpen) 
         { 
          sessions.RemoveAt(i); 
          --i; 
         } 
        } 
       } 
       catch(Exception ex) 
       { 
       } 
      } 
     } 
     catch (SocketException socketEx) 
     { 
     } 
     finally 
     { 
      handler.Close(); 

      foreach (Session s in sessions) 
      { 
       s.Stop(); 
       HostConnected = false; 
      } 
     } 
    }