Donc, pour un peu d'arrière-plan: Cette classe est créée pour accepter et répondre aux appels effectués à distance dans un format HTTP. Le problème est lorsque la méthode de la demande est POST, parfois la demande est traitée correctement, mais la plupart du temps la classe finit par être irresponsable. En outre, les lignes "Debug1" et "Debug2" ne sont jamais écrites sur la console, même lorsque la requête est traitée correctement. La ligne "Debug3" n'apparaît que lorsque la requête est traitée correctement.Comportement étrange: TcpListener
Je sais que cela aura probablement l'air désordonné, C# est seulement un passe-temps pour moi, et j'apprends :) Merci d'avoir passé du temps à parcourir ce code!
Voici le code:
class WebServer
{
private TcpListener myListener;
public WebServer(int port)
{
//Threading the listener
try
{
myListener = new TcpListener(IPAddress.Any, port) ;
myListener.Start();
Thread th = new Thread(new ThreadStart(StartListen));
th.Start() ;
}
catch(Exception e)
{
Logs.Add("WebServer|An Exception Occurred while Listening :" +e.ToString());
}
}
private void StartListen()
{
int iStartPos = 0;
string sHttpVersion;
string sResponse = "";
string sCode = " 200 OK";
while(true)
{
//Accept a new connection
Socket mySocket = myListener.AcceptSocket();
if(mySocket.Connected)
{
Byte[] bReceive = new Byte[1024];
int i = mySocket.Receive(bReceive,bReceive.Length,SocketFlags.None);
string sBuffer = Encoding.ASCII.GetString(bReceive).TrimEnd('\0');
iStartPos = sBuffer.IndexOf("HTTP",1);
sHttpVersion = sBuffer.Substring(iStartPos,8); //http version (ex: "HTTP/1.1")
if (sBuffer.StartsWith("GET/"))
{
Logs.Add("WebServer|Connected:" + mySocket.RemoteEndPoint.ToString());
sResponse = ArrayToJson();
}
else if (sBuffer.StartsWith("POST"))
{
Console.WriteLine("Debug1");
//This is a POST request, so more data is waiting to be retreived...
bReceive = new Byte[2048];
i = mySocket.Receive(bReceive,bReceive.Length,SocketFlags.None);
sBuffer = Encoding.ASCII.GetString(bReceive).TrimEnd('\0');
Console.WriteLine("Debug2");
//Parsing the request
string[] sParams = sBuffer.Split(',');
Console.WriteLine(sParams.Length);
Console.WriteLine("Debug3: {0} - {1} - {2} - {3} - {4}", sParams[0], sParams[1], sParams[2], sParams[3], sParams[4]);
//I do what needs to be done here
Logs.Add("WebServer|BotStartRequest:" + mySocket.RemoteEndPoint.ToString());
sResponse = "Accepted";
}
//Sending response and closing socket
SendHeader(sHttpVersion, "text/html", sResponse.Length, sCode, ref mySocket);
SendToBrowser(sResponse, ref mySocket);
mySocket.Close();
}
}
}
}
}
Avez-vous essayé d'augmenter la taille du tampon de réception? Si le navigateur envoie> 2048 octets, je suppose que vous pourriez vous retrouver dans une situation où vous avez seulement lu une partie de la demande, et la conversation serait laissée dans un état «douteux». –
Je doute que ce soit le problème parce que je n'ai jamais vu ce corps se rapprocher de 2048 octets. J'ai aussi fait mes tests avec seulement quelques requets différents, la plupart d'entre eux ont exactement le même corps, et ça fonctionne encore aléatoirement ... – Ben
Ceci est porté C++, pas C# idiomatique, donc cela rend le débogage très difficile. Vous avez besoin d'un try/catch + log dans votre boucle while pour commencer à comprendre cela. La façon dont vous gérez les tampons est inefficace et probablement la source de vos problèmes. –