我的程序中的套接字有问题。我正在开发一个嵌入另一个程序的FTP服务器,为了做到这一点,我创建了一个套接字和一个TCPListener。在这种情况下我的问题出现了:
- 我第一次打开连接,如果没有人连接我关闭它,一切都很好;否则,如果有人连接到我的FTP服务器,一切正常;
- 如果,在第一次关闭连接并再次打开它之后没有任何人连接,我得到一个SocketException“socket / ip address / port”已经在使用中,我无法再次实例化。
我的功能代码是:
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;
}
}
我知道在Compact框架中没有Timeout调用,所以,我该怎么做才能避免我的socket仍然在后台打开。
哦,对,另外一个额外信息:
我的ftp服务器实际上使用OpenNETCF FTP库
答案 0 :(得分:0)
好的,我已经解决了使用SetSocketOption并且我已经改变了一些代码。现在就是这样:
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;
}
}
}