服务器代码(做了简化)class Client:IDisposable
{
Socket _client;
NetworkStream _stream; byte[] buffer; bool IsDisposed; public Client(Socket client)
{
this._client = client;
this._stream = new NetworkStream(client, FileAccess.Read);
this.buffer = new byte[256];
this.read();
} private void read()
{
_stream.BeginRead(buffer, 0, buffer.Length, ReadCallback, null);
} private void ReadCallback(IAsyncResult ar)
{
int i = _stream.EndRead(ar);
if (Encoding.Unicode.GetString(buffer, 0, i) == "quit")
this.Close();
if (!IsDisposed)
_stream.BeginRead(buffer, 0, buffer.Length, ReadCallback, null); } ~Client()
{
Dispose(false);
} private void Close()
{
Dispose(true);
} #region IDisposable 成员 void IDisposable.Dispose()
{
Dispose(true);
} #endregion private void Dispose(bool disposing)
{
if (disposing)
{
//清理托管资源
}
//清理非托管资源
Console.WriteLine("{0}正在释放", this._client.RemoteEndPoint); _stream.Close();
_stream = null;
_client.Shutdown(SocketShutdown.Both);
_client.Close();
_client = null;
IsDisposed = true; Console.WriteLine("已被释放");
} } class Program
{
static List<Client> clients = new List<Client>();
static Socket serverSocket;
static void Main(string[] args)
{
serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
serverSocket.Bind(new IPEndPoint(Dns.GetHostAddresses(Dns.GetHostName())[0], 5000));
serverSocket.Listen(100);
serverSocket.BeginAccept(Accept_Callback, null); //无限阻塞,为了演示需要
Thread.Sleep(Timeout.Infinite);
} private static void Accept_Callback(IAsyncResult ar)
{
Socket client = serverSocket.EndAccept(ar);
Console.WriteLine(client.RemoteEndPoint);
clients.Add(new Client(client)); serverSocket.BeginAccept(Accept_Callback, null);
}
}
{
Socket _client;
NetworkStream _stream; byte[] buffer; bool IsDisposed; public Client(Socket client)
{
this._client = client;
this._stream = new NetworkStream(client, FileAccess.Read);
this.buffer = new byte[256];
this.read();
} private void read()
{
_stream.BeginRead(buffer, 0, buffer.Length, ReadCallback, null);
} private void ReadCallback(IAsyncResult ar)
{
int i = _stream.EndRead(ar);
if (Encoding.Unicode.GetString(buffer, 0, i) == "quit")
this.Close();
if (!IsDisposed)
_stream.BeginRead(buffer, 0, buffer.Length, ReadCallback, null); } ~Client()
{
Dispose(false);
} private void Close()
{
Dispose(true);
} #region IDisposable 成员 void IDisposable.Dispose()
{
Dispose(true);
} #endregion private void Dispose(bool disposing)
{
if (disposing)
{
//清理托管资源
}
//清理非托管资源
Console.WriteLine("{0}正在释放", this._client.RemoteEndPoint); _stream.Close();
_stream = null;
_client.Shutdown(SocketShutdown.Both);
_client.Close();
_client = null;
IsDisposed = true; Console.WriteLine("已被释放");
} } class Program
{
static List<Client> clients = new List<Client>();
static Socket serverSocket;
static void Main(string[] args)
{
serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
serverSocket.Bind(new IPEndPoint(Dns.GetHostAddresses(Dns.GetHostName())[0], 5000));
serverSocket.Listen(100);
serverSocket.BeginAccept(Accept_Callback, null); //无限阻塞,为了演示需要
Thread.Sleep(Timeout.Infinite);
} private static void Accept_Callback(IAsyncResult ar)
{
Socket client = serverSocket.EndAccept(ar);
Console.WriteLine(client.RemoteEndPoint);
clients.Add(new Client(client)); serverSocket.BeginAccept(Accept_Callback, null);
}
}
客户端代码public class NetCommunicator
{
/// <summary>
/// 客户端套接字。
/// </summary>
private TcpClient _client;
private NetworkStream _stream; public NetCommunicator()
{
_client = new TcpClient(new IPEndPoint((Dns.GetHostAddresses(Dns.GetHostName()))[0], 8000));
_client.Connect(new IPEndPoint(IPAddress.Parse("192.168.0.100"), 5000));
_stream = _client.GetStream();
} ///<summary>
/// 关闭套接字,释放所有资源。
/// </summary>
public void Close()
{
try
{
_stream.Write(Encoding.Unicode.GetBytes("quit"), 0, Encoding.Unicode.GetByteCount("quit"));
}
catch { } finally
{
_client.Client.Shutdown(SocketShutdown.Both);
_client.Client.Close();
_stream.Close();
_client.Close();
_stream = null;
_client = null;
}
} } class Program
{ static void Main(string[] args)
{
NetCommunicator communicator = new NetCommunicator();
try
{
//Do something Console.ReadLine();//敲回车后关闭
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
} finally
{
communicator.Close();
} }
}
挡在客户端启动程序后 在按回车关闭它 然后再次打开后
在_client.Connect(new IPEndPoint(IPAddress.Parse("192.168.0.100"), 5000)); 出现异常未处理 System.Net.Sockets.SocketException
Message="通常每个套接字地址(协议/网络地址/端口)只允许使用一次。 192.168.0.100:5000"
Source="System"
ErrorCode=10048
NativeErrorCode=10048
StackTrace:
在 System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
在 System.Net.Sockets.Socket.Connect(EndPoint remoteEP)
在 System.Net.Sockets.TcpClient.Connect(IPEndPoint remoteEP)
在 client.NetCommunicator..ctor() 位置 C:\Documents and Settings\张威虎\My Documents\Visual Studio 2008\Projects\socketFinalize\client\Program.cs:行号 22
在 client.Program.Main(String[] args) 位置 C:\Documents and Settings\张威虎\My Documents\Visual Studio 2008\Projects\socketFinalize\client\Program.cs:行号 55
在 System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
在 System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
在 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
在 System.Threading.ThreadHelper.ThreadStart_Context(Object state)
在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
在 System.Threading.ThreadHelper.ThreadStart()
InnerException: 但我再等一会后 再次打开客户端(服务端一直开着) 就不出现了
{
try
{
int i = _stream.EndRead(ar);
if (Encoding.Unicode.GetString(buffer, 0, i) == "quit")
this.Close();
_stream.BeginRead(buffer, 0, buffer.Length, ReadCallback, null);
}
catch (IOException)//当客户端按右上方差号关闭时引发
{
this.Close();
} }
当我直接关闭客户端后(按差号) 再次打开就不出现异常了 让我疑惑的就是 为什么我在finally里面显式的调用close它关不了
直接结束程序 就能释放