绑定时 C# 异步 SocketException
Posted
技术标签:
【中文标题】绑定时 C# 异步 SocketException【英文标题】:C# async SocketException while binding 【发布时间】:2015-01-25 16:09:29 【问题描述】:我正在使用异步套接字在 C# 上开发客户端-服务器应用程序。当我监听连接时,我不断收到此错误
“System.Net.Sockets.SocketException”类型的未处理异常 发生在 System.dll 中
附加信息:每个套接字地址(协议/网络地址/端口)通常只允许使用一次
这是发生此异常的行:
_listener.Bind(new IPEndPoint(0, port));
代码在Listener.Start(int port)
下。在主程序中,我是这样调用方法的:
void btnListen_Click(object sender, EventArgs e)
_listener = new Listener();
_listener.Accepted += new Listener.SocketAcceptedHandler(listener_Accepted);
_listener.Start(8192);
我正在我的 PC 中测试客户端和服务器应用程序。
这是Listener
类。
namespace serverPC
class Listener
public delegate void SocketAcceptedHandler(Socket e);
public event SocketAcceptedHandler Accepted;
Socket _listener;
public int Port;
public bool Running
get;
private set;
public Listener() Port = 0;
public void Start(int port)
if (Running)
return;
_listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_listener.Bind(new IPEndPoint(0, port)); // This is where the SocketException error occurs
_listener.Listen(0);
_listener.BeginAccept(acceptedCallback, null);
Running = true;
public void Stop()
if (!Running)
return;
_listener.Close();
Running = false;
void acceptedCallback(IAsyncResult ar)
try
Socket s = _listener.EndAccept(ar);
if (Accepted != null)
Accepted(s);
catch
if (Running)
try
_listener.BeginAccept(acceptedCallback, null);
catch
这是Client
类。
namespace serverPC
struct ReceiveBuffer
public const int BUFFER_SIZE = 1024;
public byte[] Buffer;
public int ToReceive;
public MemoryStream BufStream;
public ReceiveBuffer(int toRec)
Buffer = new byte[BUFFER_SIZE];
ToReceive = toRec;
BufStream = new MemoryStream(toRec);
public void Dispose()
Buffer = null;
ToReceive = 0;
Close();
if (BufStream != null)
BufStream.Dispose();
public void Close()
if (BufStream != null && BufStream.CanWrite)
BufStream.Close();
class Client
byte[] lenBuffer;
ReceiveBuffer buffer;
Socket _socket;
public IPEndPoint EndPoint
get
if (_socket != null && _socket.Connected)
return (IPEndPoint)_socket.RemoteEndPoint;
return new IPEndPoint(IPAddress.None, 0);
public delegate void DisconnectedEventHandler(Client sender);
public event DisconnectedEventHandler Disconnected;
public delegate void DataReceivedEventHandler(Client sender, ReceiveBuffer e);
public event DataReceivedEventHandler DataReceived;
public Client(Socket s)
_socket = s;
lenBuffer = new byte[4];
public void Close()
if (_socket != null)
_socket.Disconnect(false);
_socket.Close();
buffer.Dispose();
_socket = null;
lenBuffer = null;
Disconnected = null;
DataReceived = null;
public void ReceiveAsync()
_socket.BeginReceive(lenBuffer, 0, lenBuffer.Length, SocketFlags.None, receiveCallback, null);
void receiveCallback(IAsyncResult ar)
try
int rec = _socket.EndReceive(ar);
if (rec == 0)
if (Disconnected != null)
Disconnected(this);
return;
if (rec != 4)
throw new Exception();
catch (SocketException se)
switch (se.SocketErrorCode)
case SocketError.ConnectionAborted:
case SocketError.ConnectionReset:
if (Disconnected != null)
Disconnected(this);
return;
break;
catch (ObjectDisposedException)
return;
catch (NullReferenceException)
return;
catch (Exception ex)
Console.WriteLine(ex.Message);
return;
buffer = new ReceiveBuffer(BitConverter.ToInt32(lenBuffer, 0));
_socket.BeginReceive(buffer.Buffer, 0, buffer.Buffer.Length, SocketFlags.None, receivePacketCallback, null);
void receivePacketCallback(IAsyncResult ar)
int rec = _socket.EndReceive(ar);
if (rec <= 0)
return;
buffer.BufStream.Write(buffer.Buffer, 0, rec);
buffer.ToReceive -= rec;
if(buffer.ToReceive > 0)
Array.Clear(buffer.Buffer, 0, buffer.Buffer.Length);
_socket.BeginReceive(buffer.Buffer, 0, buffer.Buffer.Length, SocketFlags.None, receivePacketCallback, null);
return;
if (DataReceived != null)
buffer.BufStream.Position = 0;
DataReceived(this, buffer);
buffer.Dispose();
ReceiveAsync();
为什么会收到 SocketException 错误?任何帮助表示赞赏。谢谢!
【问题讨论】:
问题解决了吗?找到解决办法了吗? 【参考方案1】:所以要检查的事情很明显 - 端口 8192 上已经有东西在监听,或者有其他原因导致您的机器拒绝您的程序打开该端口(防火墙等)。
另一个问题是,当您使用“正在运行”检查阻止绑定两次时,您只是为侦听器的实例执行此操作 - 点击按钮将创建一个全新的侦听器并尝试让它在端口 8192 上侦听- 因为你已经绑定了一个监听器,所以会因为那个异常而失败。
【讨论】:
你提到的第一件事没有问题。我的防火墙允许我的应用程序,没有其他东西在监听端口(我已经检查过了)。我不太明白你在这里的意思->“你通过“运行”检查阻止绑定两次,你只是为监听器的实例这样做” 我现在明白你在后半部分的意思了。以上是关于绑定时 C# 异步 SocketException的主要内容,如果未能解决你的问题,请参考以下文章
c# datagridview 绑定数据时逐行显示并且有进度条。问题如下:
C# 理解阻塞 UI 和异步/等待与 Task.Run 的问题?
Httpclient在.net core3.1上成功运行,但更新到.net 5中连接超时(System.Net.Sockets.SocketException (10060)) C#