【发布时间】:2020-10-12 10:15:52
【问题描述】:
我有一个在读取时阻塞的套接字线程。我将套接字上的接收超时设置为 30 秒;如果没有读取字节,则读取进入 IO 异常(内部异常:错误代码:10060)。我结束进程并关闭流并将线程设置为空。出于某种原因,我似乎无法关闭套接字连接。我不确定错误在哪里。以下是我的代码:
public class SampleClientSocket
{
private Socket cltSocket = null;
private volatile bool readyToRecv = false;
NetworkStream ns;
BinaryReader br;
BinaryWriter wr;
private string _caller = "SampleSocketClient";
Thread workerThread;
static void Main(string[] args)
{
BeginWork();
}
public void BeginWork()
{
try
{
IPEndPoint ipe = new IPEndPoint("127.0.0.1", 5000);
cltSocket = new Socket(ipe.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
cltSocket.Connect(ipe);
cltSocket.ReceiveTimeout = 30000;
cltSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
workerThread = new Thread(doWork_01);
workerThread.Start();
readyToRecv = true;
}
catch (Exception f)
{
Console.WriteLine(this._caller + f.StackTrace);
}
}
private void doWork_01()
{
try
{
this.ns = new NetworkStream(this.cltSocket);
this.br = new BinaryReader(this.ns);
this.wr = new BinaryWriter(this.ns);
readyToRecv = true;
this._lastSocketRead = toUnixTime(DateTime.Now);
}
catch
{
Console.WriteLine(this._caller + "ERROR OPENING STREAMS.");
readyToRecv = false;
}
while (this.readyToRecv)
{
bool _etxEncountered = false;
MemoryStream currentMessage = new MemoryStream();
byte buf = (byte)0;
while (!_etxEncountered)
{
try
{
buf = this.br.ReadByte();
}
catch (EndOfStreamException)
{
Console.WriteLine(this._caller + "ERROR: END OF STREAM");
readyToRecv = false;
_etxEncountered = true;
break;
}
catch (ObjectDisposedException)
{
Console.WriteLine(this._caller + "ERROR: Stream is closed!");
readyToRecv = false;
_etxEncountered = true;
break;
}
catch (IOException i)
{
Console.WriteLine(this._caller + "ERRORSTACK: IOException!" + i.StackTrace);
//if the ReeceiveTimeout is reached an IOException will be raised...
/// with an InnerException of type SocketException an ErrorCode 10060
var socketExpert = i.InnerException as SocketException;
if (socketExpert.ErrorCode != 10060)
{
Console.WriteLine(this._caller + "ERROR: IOException!" + socketExpert.ErrorCode);
readyToRecv = false;
_etxEncountered = true;
}
else
{
Console.WriteLine(this._caller + "Read: IOException for timeout! NOT DISCONNECTING");
readyToRecv = false;
_etxEncountered = true;
break;
}
}
catch (Exception f)
{
Console.WriteLine(this._caller + "Unknown exception" + f.StackTrace);
var socketExpert = f.InnerException as SocketException;
Console.WriteLine(this._caller + "Error code number: " + socketExpert.ErrorCode);
readyToRecv = false;
_etxEncountered = true;
}
if (buf.Equals(0x03) == true)
{
_etxEncountered = true;
break;
}
else if (buf.Equals(0x02) == false)
{
try
{
currentMessage.WriteByte(buf);
}
catch (Exception)
{
}
}
}
try { Thread.Sleep(10); }
catch { }
} // end while
EndWork();
}
public void EndWork()
{
try
{
readyToRecv = false;
//close streams
this.br.BaseStream.Flush();
this.br.Close();
this.br.Dispose();
this.wr.Flush();
this.wr.Close();
this.wr.Dispose();
this.ns.Flush();
this.ns.Close();
this.ns.Dispose();
this.cltSocket.Shutdown(SocketShutdown.Both);
//this.cltSocket.Disconnect(true);
this.cltSocket.Close();
this.cltSocket.Dispose();
this.cltSocket = null;
Console.WriteLine(this._caller + "GOODBYE...");
try
{
this.workerThread.Join(1000);
if (this.workerThread.IsAlive)
{
this.workerThread.Abort();
}
}
catch { }
this.workerThread = null;
}
catch
{
this.readyToRecv = false;
this.workerThread = null;
}
return;
}
}
感谢任何帮助。
【问题讨论】:
-
"我似乎无法关闭套接字连接。"这是什么意思?你有例外吗?那是什么异常?你得到一个编译器错误吗?请解释会发生什么。
-
套接字连接仍然打开,另一端可以发送数据,我的线程即使在第一个 30 秒后仍然接收字节并进入 IOException。
-
是socket没有关闭还是Backgroundworker没有关闭。尝试从 cmd.exe >Netstat -a 并检查端口号的状态以检查套接字的状态。
-
套接字没有关闭。在 netstat -ao 中,我仍然看到客户端正在连接。在端口 5000 上建立连接;但是,在我的日志中,线程正在被处理。
-
@jdweng:你为我指明了正确的方向。有一个线程没有正确处理。所以,代码永远不会结束。感谢您指出问题。我不确定如何将您的评论标记为答案。
标签: c# sockets synchronous ioexception