c# - .NET TcpListener Stop method does not stop the listener when there is a child process -
i working legacy tcp server code works sockets directly written in .net 2.0 , earlier. server has feature 'stop' , 'start' accepting client connections.
to troubleshoot issue run server in console mode admin user. on top of have eliminated socket accept thread equation , code like:
tcplistener = new tcplistener(ipaddress.any, this.port); tcplistener.start(); and
tcplistener.stop(); this called different methods. have debugged code , pretty sure code executes once. however, issue call stop not releases socket address , subsequent call start therefore fails error "only 1 usage of each socket address (protocol/network address/port) permitted". can confirm processexplorer server still listening on server port.
when write small console app uses same code snippets works fine. have tried tracing .net network , socket libraries, there no error or indicate problems there.
it not clear me why call stop not release socket address?
update: after more investigation turns out there strange effect of child process launch tcplistener. have made 'bare bone' sample code illustrates issue:
using system; using system.diagnostics; using system.net; using system.net.sockets; using system.reflection; using system.threading; namespace tcplistenerstartstop { class mytcplistener { public static void main(string[] args) { int32 port = 13000; if (args.length > 0) // indicates child process { thread.sleep(4000); // child nothing , wait few seconds } else // parent play tcplistener { //launchchildprocess(); // launch child here , listener restart fine?!? var tcplistener = new tcplistener(ipaddress.any, port); tcplistener.start(); console.writeline("starting test in 2 seconds..."); thread.sleep(2000); launchchildprocess(); // launch child here , listener restart not fine?!? tcplistener.stop(); console.writeline("stopped."); thread.sleep(1000); tcplistener.start(); console.writeline("started"); } console.writeline("all good, no exceptions :)"); } private static void launchchildprocess() { process process = new process(); var processstartinfo = new processstartinfo { createnowindow = true, filename = assembly.getexecutingassembly().location, useshellexecute = false, // comment out line out listener restart fine?!? arguments = "child" }; process.startinfo = processstartinfo; process.start(); } } } as can see code if launch child process before creating listener fine, if after listener restart fails. has useshellexecute = false option child process.
not sure if .net bug or special behavior not aware of?
the real reason behavior tcplistener socket handle inherited child process many other handles. discussions on topic can found here , here.
one obvious solution launch child process before initializing tcplistener.
another solution have useshellexecute = true avoid socket handle inheritance.
ideal solution set socket handle option prevent inheritance child process, not sure if can done in .net.
Comments
Post a Comment