下面的代码将失败,因为Bind()在尚未准备好的套接字上被调用",即使有代码准备套接字也是如此。准备套接字的代码超出了范围(另一个Try块)。
// prepare socket
try
{
socket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
}
catch (Exception e)
{
log.write("socket preparation failed");
}
finally
{
if (socket != null)
{
socket.Shutdown(SocketShutdown.Both);
socket.Close();
}
}
// bind
try
{
socket.Bind(endPoint);
}
catch (Exception e)
{
log.write("Bind() failed");
}
finally
{
if (socket != null)
{
socket.Shutdown(SocketShutdown.Both);
socket.Close();
}
}
// enable listening
try
{
socket.Listen(1000);
}
catch (Exception e)
{
log.write("Listen() failed");
}
finally
{
if (socket != null)
{
socket.Shutdown(SocketShutdown.Both);
socket.Close();
}
}
答案 0 :(得分:2)
这是编写它的一种方法。 finally
是外部范围的一部分,而您的所有catches
都在内部范围内。我在每个throwing
之后catch
,但您可以采用不同的方式处理它。
请注意,每个finally
子句在其对应的try
子句超出范围时执行,而不是在方法存在时执行。
Socket socket;
try
{
// prepare socket
try
{
socket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
}
catch
{
log.write("socket preparation failed");
throw;
}
// bind
try
{
socket.Bind(endPoint);
}
catch
{
log.write("Bind() failed");
throw;
}
// enable listening
try
{
socket.Listen(1000);
}
catch
{
log.write("Listen() failed");
throw;
}
}
finally
{
if (socket != null)
{
socket.Shutdown(SocketShutdown.Both);
socket.Close();
}
}
答案 1 :(得分:0)
如果异常总是以同样的方式对待,为什么不尝试这种方式......
string message = string.Empty;
try
{
message = "socket preparation failed";
socket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
message = "Bind() failed";
socket.Bind(endPoint);
message = "Listen() failed";
socket.Listen(1000);
message = string.Empty;
}
catch
{
log.write(message);
}
finally
{
if (socket != null)
{
socket.Shutdown(SocketShutdown.Both);
socket.Close();
}
}
答案 2 :(得分:0)
在这种情况下,我喜欢使用自定义包装器类,我发现它们更整洁,并且能够根据您的需求进行自定义(特别是在以整洁的方式抛出错误时)
所以你可以编写一个实现Socket
的类,我们称之为CustomSocket
public class CustomSocket : Socket {
private EndPoint endPoint;
public CustomSocket(EndPoint endPoint, SocketType socketType, ProtocolType protocolType)
: base(endPoint.AddressFamily, socketType, protocolType) {
this.endPoint = endPoint;
}
public virtual void Bind() {
try {
base.Bind(endPoint);
} catch {
// do logging here
throw new Exception("Bind() failed");
}
}
public virtual void Listen(int backlog) {
try {
base.Listen(backlog);
} catch {
// do logging here
throw new Exception("Listen() failed");
}
}
public void Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
}
protected override void Dispose(bool disposing) {
base.Dispose(disposing);
}
}
然后你可以这样实现它:
using (CustomSocket socket = new CustomSocket(new IPEndPoint(new IPAddress(new byte[1]), 5000), SocketType.Stream, ProtocolType.Tcp)) {
try {
socket.Bind();
socket.Listen(1000);
} catch (Exception ex) {
// do stuff with ex here
}
}
此外,实施此using
方法会使您不必手动拨打Close()
和/或Shutdown()
。 (using
在结束时自动调用Dispose()
,而Dispose()
与Close()
相同。调用Close()
时,如果您没有{39} ; t已经明确发起了Shutdown()
它会为你启动它)