Ok, désolé pour la première question qui était une mauvaise question. Deuxième essai. J'ai créé un serveur Web (ou un répondeur?) En utilisant les bibliothèques C# et System.Net. Voici serveur variables publiques:Mon serveur web ne trouve pas les sous-répertoires
#region "Variables"
private TcpListener _TcpListener;
private Thread _ListenThread;
private string _ServerDataPath = "";
private string _Log = "[XMS LOG] Date : " + DateTime.Now.ToString("r") + "\r\n";
public List<string> Defaults;
public Dictionary<string, string> Mimes;
#endregion
private int _SendBufferSize = 2048;
private int _ReceiveBufferSize = 2048;
#region "Properties"
public int SendBufferSize
{
get { return _SendBufferSize; }
set
{
if (value <= 0)
{
return;
}
_SendBufferSize = value;
}
}
public int ReceiveBufferSize
{
get { return _ReceiveBufferSize; }
set
{
if (value <= 0)
{
return;
}
_ReceiveBufferSize = value;
}
}
public TcpListener Listener
{
get { return _TcpListener; }
}
public Thread ListenThread
{
get { return _ListenThread; }
}
public String Path
{
get { return _ServerDataPath; }
}
#endregion
Voici le code de ma méthode listen:
private void Listen()
{
Socket cur = null;
try
{
// Infinite loop
while(true)
{
// Accept incoming socket
cur = _TcpListener.AcceptSocket();
// Limit socket buffers
cur.SendBufferSize = SendBufferSize; cur.ReceiveBufferSize = ReceiveBufferSize;
// Get request
byte[] Request = new byte[ReceiveBufferSize];
int RequestSize = cur.Receive(Request);
string RequestStr = Encoding.Default.GetString(Request);
// Clients send empty requests filled with nulls
// To prevent lag if request is empty then directly close stream
if (string.IsNullOrWhiteSpace(RequestStr) || string.IsNullOrEmpty(RequestStr))
{
cur.Close();
}
else
{
// Process request
Process(cur, RequestStr);
cur.Close();
}
}
}
catch (Exception ex)
{
SendError(cur, "TCPClient Listening Error", "500", "Runtime Exception", ex);
}
}
Cette méthode est en cours d'exécution sur un thread. Voici ma méthode de processus qui traite les requêtes http:
private void Process(Socket skt, string Request)
{
try
{
// Split all the request from line terminators
string[] RequestSplit = Request.Split(new string[] { "\r", "\n", "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
// Get Request at top of this split array
string GetRequest = RequestSplit[0];
// Trim
GetRequest = GetRequest.Trim();
// Is it a get request?
if (!GetRequest.StartsWith("GET"))
{
// Send error and return
SendError(skt, "Bad Request : " + GetRequest, "400", "Bad Request");
return;
}
// Split Get Request
string[] GetRequestSplit = GetRequest.Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
// Is Request Legal?
// Classical GET requests generally has 3 parts:
// GET {FileName} HTTP/1.1
// If we get length smaller than 3 then send error
if (GetRequestSplit.Length < 3)
{
SendError(skt, "Bad Request : " + GetRequest, "400", "Bad Request");
return;
}
Log(GetRequest);
// As usual middle one is file
string File = GetRequestSplit[1];
// We patch server path directory to this file string
File = _ServerDataPath + File;
// Control if it is a directory
// If it is a directory then control default files
bool IsIndex = false;
if (System.IO.Directory.Exists(File))
{
// This must be an index file
IsIndex = true;
}
// Not index file? No problem
// I just control that if there
// Is a file called like that
if (!IsIndex)
{
// Oops accidents happen.
// Cannot find the file that you requested.
if (!System.IO.File.Exists(File))
{
SendError(skt, "Cannot find selected file", "404", "Not Found");
return;
}
// Ok we a legal file
// Go out and send it!
}
// But if file is an index?
// Simple, loop over every default file
else
{
// No defaults defined by user?
// Sorry, we do not serve index files.
if (Defaults.Count == 0)
{
SendError(skt, "Default files are not allowed", "404", "Not Found");
return;
}
for (int i = 0; i < Defaults.Count; i++)
{
if (System.IO.File.Exists(File + "\\" + Defaults[i]))
{
// Get the index file. Patch it.
File += "\\" + Defaults[i];
goto send;
}
}
// Does not contain any default?
// Send error again.
SendError(skt, "Cannot find default file in requested directory", "404", "Not Fount");
return;
}
send:
// Here we are, sending data...
// Byte buffer for sending
byte[] Buffer = System.IO.File.ReadAllBytes(File);
// Mime?
string Mime = GetMime(File);
// Directly send while it is hot already!
SendMessage(skt, Buffer, true, "200", "OK", Mime);
}
catch (Exception ex)
{
SendError(skt, "Unknown exception", "500", "Internal Exception");
}
}
et ma Méthode d'envoi de message:
public void SendMessage(Socket skt, byte[] message, bool includeHeader = false, string statusCode = "200", string statusMessage = "OK", string mime = "text/plain")
{
if (skt == null) { return; }
string header = "";
if (includeHeader)
{
header = "HTTP/1.1 " + statusCode + " " + statusMessage + "\r\n";
header += "Server: XMServer Module\r\n";
header += "Date: " + DateTime.Now.ToString("r") + "\r\n";
header += "Content-Type: " + mime + "; charset=utf-8\r\n";
header += "Connection: Closed";
header += "\r\n\r\n";
}
List<byte> buffer = Encoding.Default.GetBytes(header).ToList();
buffer.AddRange(message);
skt.Send(buffer.ToArray());
}
Je pense qu'il n'y a pas de problème dans les méthodes sendError, getMime ou StrIsFile donc je ne les mets pas ici. Ceci est une classe nommée XMServer. Voici mon code de départ:
XMServer server = new XMServer(8080, "..\\web\\", 4096, 1024);
server.Mimes = MIMES;
server.Defaults = DEFAULTS;
server.Start();
Le problème est, le répertoire du serveur est défini comme .. \ web \ je mets là un fichier index.html et tapez 127.0.0.1:8080 dans le navigateur et le serveur envoie index.html page. C'est bien et ce que j'essaie de mettre en œuvre. J'ai créé un dossier appelé "docs" dans le dossier "web" et mis un dossier "images" dans le dossier "docs". Et mettre un fichier index.html dans le dossier "docs". index.html content:
<html>
<head>
<title> Documentation </title>
<meta charset="utf-8"/>
</head>
<body>
<!-- This is where error pops out -->
<img src="images/logo.png"/>
</body>
</html>
Le serveur envoie le fichier index.html correctement. Mais la page envoie une requête au serveur comme "GET /images/logo.png HTTP/1.1" (Juste un exemple, je ne suis pas sûr que la requête soit parfaitement égale à celle-ci). Le serveur essaie d'envoyer ".. \ web \ images \ logo.png", pas ".. \ web \ docs \ images \ logo.png" et enregistre une erreur dans le fichier (j'ai créé une méthode pour cela). La même chose se produit lorsque nous essayons de donner un lien vers un autre fichier html dans les sous-répertoires du dossier web. Comment puis-je battre ça? Et je suis sûr que mon code est inefficace, montrez-moi mes erreurs. toute aide serait appréciée.
s'il vous plaît lire guid sur la façon d'écrire une bonne question avant de poster –
Bienvenue dans Stack Overflow! Je ne trouve pas très clair quel est votre problème ... N'oubliez pas d'être clair et complet, et d'inclure des exemples (si possible et approprié). S'il vous plaît partager un code afin que nous ayons quelque chose à faire pour vous aider. - Les bonnes choses à lire pour les nouveaux membres sont [Comment demander] (http://stackoverflow.com/help/how-to-ask) et le [Tour] (http://stackoverflow.com/tour). –