20. september 2006 - 18:59
Der er
1 kommentar
NetworkStream og remoting problem
Goddag
Jeg har et, efter min overbevisning, meget underligt problem.
Det er således at jeg har en server (S) der benytter sig af remoting for udføre RPC til en filserver (F). Endvidere benyttes der en almindelig TcpListener i S til at acceptere indkomne forbindelser fra klienter (C). Ved accept startes en håndteringstråd hvori den til TcpClient'ens (skabt ved TcpListener.Accept) tilhørende NetworkStream (fra TcpClient.GetStream) gemmes til senere brug.
Problemet består nu i at hvis jeg i S prøver at læse data fra NetworkStream'en (fra K) så 'forsvinder' noget af den hvis jeg har etableret forbindelse til F. Hvis ikke jeg etablerer forbindelse til F virker al kommunikation mellem S og K uden problemer. På en eller anden vis 'koliderer' min NetworkStream og remotingservicen sådan at der ikke er data til læsning i NetworkStream.Read. Hvad pokker kan dette skyldes?
Kommunikationen mellem S of F virker upåklageligt.
Jeg håber ikke at det er for abstrakt til at kunne forstå hvad problemet er - men hvis i er i tvivl så spørg hellere end gerne.
Med venlig hilsen
Thomas René Sidor
25. september 2006 - 14:31
#1
Ok, tilsyneladende virker min kode ikke længere selvom jeg deaktiverer
remoting-delen. Det pudsige er at en del af enkelte http
forespørgelser bliver modtaget fint. En forespørgsel sendes som et
antal headers efterfulgt af en krop. De sendte headers modtages og
læses altid uden problemer med en StreamReader, men kroppen, som
læses af en NetworkStream (med metoden ReadPut() som er herunder) bliver
nogle gange aldrig modtaget - NetworkStream.Read(...) blokerer
simpelthen.
Klienten gør brug af HttpWebRequest og HttpWebResponse og serveren
acceptere nye forbindelser med en TcpListener som skaber TcpClienter.
For at gøre udviklingsforløbet nemmere har jeg pt. klienten til at
starte http serveren og filserveren. Deres processer bliver altså
spawnet af klienten.
Herunder er delen som accepterer indkomne forbindelser :
private void ListeningLoop()
{
Log("Starting HttpServer");
bool exitLoop = false;
TcpListener listener = new TcpListener(new
IPEndPoint(IPAddress.Parse("127.0.0.1"), _port));
// Registering TcpChannel for remoting
TcpChannel channel = new TcpChannel();
ChannelServices.RegisterChannel(channel, true);
Log("HttpServer up and running. Listening on port " + _port);
listener.Start();
// Listening for incomming connection to the HttpServer
while (true)
{
// If we for some reason need to stop the server, neat cleanup
can be handled here
if (exitLoop)
{
Cleanup();
break;
}
try
{
TcpClient client = listener.AcceptTcpClient();
ConnectionHandlerInstance connectionHandler = new
ConnectionHandlerInstance(client);
Thread connectionHandlerTread = new Thread(new
ThreadStart(connectionHandler.HandleConnection));
connectionHandlerTread.Start();
}
catch (Exception)
{
//Log(e.ToString());
Log("Failed to accept connection");
}
}
}
private byte[] ReadPut()
{
//Validate for content-length header
if (!_lastRequest.Headers.ContainsKey("Content-Length"))
{
WriteHttpResponse(HttpResponseCodes.BadRequest, "Content-Length
header missing");
return null;
}
else
{
int contentLength =
int.Parse(_lastRequest.Headers["Content-Length"]);
//Log("Content-Length: " + contentLength);
byte[] fullContent = new byte[contentLength];
int readBytesTotal = 0;
while (readBytesTotal < contentLength)
{
int readBytes = _networkStream.Read(fullContent,
readBytesTotal, (contentLength - readBytesTotal < 1024 ? contentLength
- readBytesTotal : 1024));
readBytesTotal += readBytes;
if (readBytes == 0)
break;
}
if (readBytesTotal == 0)
return null;
else
{
//
Console.WriteLine(ASCIIEncoding.Default.GetString(fullContent));
return fullContent;
}
}
}
Al feedback er værdsat.
Med venlig hilsen
Thomas René Sidor