I've a problem with the sockets in my program. I'm developping an FTP server embedeed in another program and in order to do that I've create a socket and a TCPListener. My problem occures in this case:
- I open the connection for the first time, if nobody connect and I close it, all fine; otherwise if somebody connect to my FTP server all works fine too;
- If, after close the connection the first time and open it again without anybody have been connected before, I get a SocketException of "socket/ip address/port" already in use and I cannot instantiate it again.
The code of my function is that:
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;
}
}
I know that in Compact framework there aren't the Timeout calls and so, what can I do to avoid that my socket still open in background.
Ohw, right, another extra info:
my ftp server actually use the OpenNETCF FTP library
Ok, I've solved using the SetSocketOption and I've changed a bit the code. Here is it now:
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;
}
}
}