C# TcpListener.AcceptSocket生成InvalidOperationException
我不熟悉C# TcpListener.AcceptSocket生成InvalidOperationException,c#,wcf,tcpclient,tcplistener,C#,Wcf,Tcpclient,Tcplistener,我不熟悉TcpListener和sockets,但我有以下代码,它们有时在我的初始化器类中从我的Wcf项目的App_代码中正确执行,但第一次正确执行时有时会显示错误,然后正确执行其他没有模式的代码 此行代码中的错误停止: Socket soc = listener.AcceptSocket(); 然后显示这些传统信息: 附加信息:不在听力中。在调用此方法之前,先调用Start()方法 但正如您所看到的,我在listener.AcceptSocket()之前调用start方法 我怀疑这是为了尝试
TcpListener
和sockets
,但我有以下代码,它们有时在我的初始化器类中从我的Wcf项目的App_代码中正确执行,但第一次正确执行时有时会显示错误,然后正确执行其他没有模式的代码
此行代码中的错误停止:
Socket soc = listener.AcceptSocket();
然后显示这些传统信息:
附加信息:不在听力中。在调用此方法之前,先调用Start()方法
但正如您所看到的,我在listener.AcceptSocket()之前调用start方法
我怀疑这是为了尝试在WCF项目中启动init守护进程
public static void AppInitialize()
{
// This will get called on startup
new Initializer().StartListener();
}
static TcpListener listener;
const int LIMIT = 5; //5 concurrent clients
private void StartListener()
{
List<int> puertos = new List<int>();
puertos.Add(5494);
puertos.Add(5495);
puertos.Add(5496);
puertos.Add(5497);
foreach (int puerto in puertos)
{
IPAddress localAddr = IPAddress.Parse(ConfigurationManager.AppSettings["ServerIP"]);
listener = new TcpListener(localAddr, puerto);
listener.Start();
for (int i = 0; i < LIMIT; i++)
{
Thread t = new Thread(new ThreadStart(Service));
t.Start();
}
}
}
private void Service()
{
while (true)
{
//Error happen hear, but listener.Start execute before... .
Socket soc = listener.AcceptSocket();
try
{
byte[] resp = new byte[2000];
var memStream = new MemoryStream();
var bytes = 0;
NetworkStream s = new NetworkStream(soc);
StreamReader sr = new StreamReader(s);
while (true)
{
string trama = "";
if (s.CanRead)
{
do
{
bytes = s.Read(resp, 0, resp.Length);
trama = Util.Util.ByteArrayToHexString(resp);
}
while (s.DataAvailable);
}
if (trama == "" || trama == null) break;
}
s.Close();
}
catch (Exception e)
{
}
finally
{
soc.Close();
}
}
}
publicstaticvoidappinitialize()
{
//这将在启动时调用
新初始值设定项().StartListener();
}
静态TcpListener侦听器;
常数int极限=5//5个并发客户端
私用
{
List puertos=新列表();
普埃尔托斯增补本(5494);
普埃尔托斯增补本(5495);
普埃尔托斯增补本(5496);
普埃尔托斯增补本(5497);
foreach(普埃尔托斯港内)
{
IPAddress localAddr=IPAddress.Parse(ConfigurationManager.AppSettings[“ServerIP]”);
侦听器=新的TcpListener(localAddr,puerto);
listener.Start();
对于(int i=0;i
嗯,不清楚为什么如果这是一个WCF程序,您直接使用Socket
或TcpListener
。WCF的目的是让它为您处理网络I/O
也就是说
之所以出现异常,是因为listener
字段在所有线程之间共享,并且一个或多个线程在第一个线程创建新的TcpListener
对象之后,但在调用Start()
之前,设法访问了AcceptSocket()
你有例外真是太好了。如果你运气不好,那么你的代码可以很容易地运行而不出现异常,然后你就会有一个更难调试的问题,因为唯一的症状是,神秘的是,不是所有的侦听器都接受任何客户机
依我看,最好设计代码,这样您就有了单独的对象实例来处理每个侦听套接字(并使用非静态成员作为值)。通过这种方式,您可以确保每个侦听器都正确且独立地运行
但是,通过将正确的TcpListener
对象传递给每个线程,您可以修复这里的代码,至少在异常方面是这样的:
private void StartListener()
{
List<int> puertos = new List<int>();
puertos.Add(5494);
puertos.Add(5495);
puertos.Add(5496);
puertos.Add(5497);
foreach (int puerto in puertos)
{
IPAddress localAddr = IPAddress.Parse(ConfigurationManager.AppSettings["ServerIP"]);
TcpListener listener = new TcpListener(localAddr, puerto);
listener.Start();
for (int i = 0; i < LIMIT; i++)
{
Thread t = new Thread(() => Service(listener));
t.Start();
}
}
}
private void Service(TcpListener listener)
{
while (true)
{
Socket soc = listener.AcceptSocket();
try
{
byte[] resp = new byte[2000];
var memStream = new MemoryStream();
var bytes = 0;
NetworkStream s = new NetworkStream(soc);
StreamReader sr = new StreamReader(s);
while (true)
{
string trama = "";
if (s.CanRead)
{
do
{
bytes = s.Read(resp, 0, resp.Length);
trama = Util.Util.ByteArrayToHexString(resp);
}
while (s.DataAvailable);
}
if (trama == "" || trama == null) break;
}
s.Close();
}
catch (Exception e) { }
finally
{
soc.Close();
}
}
}
private-void-istener()
{
List puertos=新列表();
普埃尔托斯增补本(5494);
普埃尔托斯增补本(5495);
普埃尔托斯增补本(5496);
普埃尔托斯增补本(5497);
foreach(普埃尔托斯港内)
{
IPAddress localAddr=IPAddress.Parse(ConfigurationManager.AppSettings[“ServerIP]”);
TcpListener listener=新的TcpListener(localAddr,波多黎各);
listener.Start();
对于(int i=0;i服务(侦听器));
t、 Start();
}
}
}
专用void服务(TcpListener侦听器)
{
while(true)
{
Socket soc=listener.AcceptSocket();
尝试
{
字节[]resp=新字节[2000];
var memStream=new MemoryStream();
var字节=0;
网络流s=新网络流(soc);
StreamReader sr=新的StreamReader;
while(true)
{
字符串trama=“”;
如果(s.CanRead)
{
做
{
字节=s.Read(分别为,0,分别为长度);
trama=Util.Util.ByteArrayTohextString(resp);
}
而(s.DataAvailable);
}
如果(trama==“”| | trama==null)中断;
}
s、 Close();
}
捕获(例外e){}
最后
{
soc.Close();
}
}
}
确保删除静态TcpListener侦听器代码>字段
最后一点注意:您永远不应该捕获异常,除非在代码的某一部分中,将发生的一切是,选择性地记录异常并终止进程。嗯,不清楚为什么如果这是一个WCF程序,您直接使用的是套接字
或TcpListener
。WCF的目的是让它为您处理网络I/O
也就是说
之所以出现异常,是因为listener
字段在所有线程之间共享,并且一个或多个线程在第一个线程创建新的TcpListener
对象之后,但在调用对象之前,设法访问了AcceptSocket()