我使用TcpListener启动并运行此Web服务器程序。问题是,对于通过Web浏览器(或Chrome Postman扩展)发出的每个get请求,它会捕获两个请求。
namespace Server
{
class WebServer2
{
private TcpListener listener;
private int port = 8080;
public WebServer2()
{
try
{
listener = new TcpListener(IPAddress.Parse("127.0.0.1"), port);
listener.Start();
Console.WriteLine("Listening...");
//start the thread which calls the method 'StartListen'
Thread th = new Thread(new ThreadStart(StartListen));
th.Start();
}
catch (Exception e)
{
Console.WriteLine("An Exception Occurred While Listening: " + e.ToString());
}
}
//Recieve Request
public void StartListen()
{
int iStartPos = 0;
String sRequest;
String sRequestedFile;
String sResponse = "";
while (true)
{
//Accept a new connection
Socket socket = listener.AcceptSocket();
if (socket.Connected)
{
Console.WriteLine("\nClient Connected");
Console.WriteLine("----------------");
//Receive data from the client
Byte[] bReceive = new Byte[1024];
int i = socket.Receive(bReceive, bReceive.Length, 0);
//Convert Byte to String
string sBuffer = Encoding.ASCII.GetString(bReceive);
//Only GET Request is accepted
if (sBuffer.Substring(0, 3) != "GET")
{
Console.WriteLine("Not a Get Request.");
socket.Close();
continue;
}
// Look for HTTP request
iStartPos = sBuffer.IndexOf("HTTP", 1);
// Get the HTTP text and version e.g. it will return "HTTP/1.1"
string sHttpVersion = sBuffer.Substring(iStartPos, 8);
// Extract the Requested Type and Requested file/directory
sRequest = sBuffer.Substring(0, iStartPos - 1);
//If file name not provided
if (sRequest.IndexOf(".") < 1)
{
Console.WriteLine("File name not Provided!");
socket.Close();
continue;
}
//Extract the requested file name
iStartPos = sRequest.LastIndexOf("/") + 1;
sRequestedFile = sRequest.Substring(iStartPos);
Console.WriteLine("Requested File: " + sRequestedFile);
int iTotBytes = 0;
sResponse = "";
FileStream fs = new FileStream(sRequestedFile, FileMode.Open, FileAccess.Read, FileShare.Read);
BinaryReader reader = new BinaryReader(fs);
byte[] bytes = new byte[fs.Length];
int read;
while ((read = reader.Read(bytes, 0, bytes.Length)) != 0)
{
// Read from the file and write the data to the network
sResponse = sResponse + Encoding.ASCII.GetString(bytes, 0, read);
iTotBytes = iTotBytes + read;
}
reader.Close();
fs.Close();
SendHeader(sHttpVersion, "text/html", iTotBytes, " 200 OK", ref socket);
SendToBrowser(bytes, ref socket);
socket.Send(bytes, bytes.Length, 0);
socket.Close();
}
}
}
// Overloaded Function, takes string, convert to bytes and calls
// overloaded sendToBrowserFunction.
public void SendToBrowser(String sData, ref Socket socket)
{
SendToBrowser(Encoding.ASCII.GetBytes(sData), ref socket);
}
/// Sends data to the browser (client)
public void SendToBrowser(Byte[] bSendData, ref Socket socket)
{
int numBytes = 0;
try
{
if (socket.Connected)
{
if ((numBytes = socket.Send(bSendData, bSendData.Length, 0)) == -1)
Console.WriteLine("Socket Error");
}
else
Console.WriteLine("Connection Dropped!");
}
catch (Exception e)
{
Console.WriteLine("Error: {0} ", e);
}
}
// This function send the Header Information to the client (Browser)
public void SendHeader(string sHttpVersion, string sMIMEHeader, int iTotBytes, string sStatusCode, ref Socket socket)
{
String sBuffer = "";
Byte[] bSendData;
if (sStatusCode.Equals("404") || sStatusCode.Equals("400"))
{
sBuffer = sBuffer + sHttpVersion + sStatusCode + "\r\n";
sBuffer = sBuffer + "Server: MyServer\r\n";
sBuffer = sBuffer + "Content-Length: " + 0 + "\r\n\r\n";
bSendData = Encoding.ASCII.GetBytes(sBuffer);
SendToBrowser(bSendData, ref socket);
}
else
{
sBuffer = sBuffer + sHttpVersion + sStatusCode + "\r\n";
sBuffer = sBuffer + "Server: MyServer\r\n";
sBuffer = sBuffer + "Content-Type: " + sMIMEHeader + "\r\n";
sBuffer = sBuffer + "Accept-Ranges: bytes\r\n";
sBuffer = sBuffer + "Content-Length: " + iTotBytes + "\r\n\r\n";
bSendData = Encoding.ASCII.GetBytes(sBuffer);
SendToBrowser(bSendData, ref socket);
}
}
}
}
Single request made by chrome against http://localhost:8080/page1.html
Request made by Postman Extension
有趣的是,当我通过我的客户端程序(使用TcpClient)发送请求时,一切正常。
答案 0 :(得分:0)
我测试了你的服务器并获得了类似的结果:
然后我遇到了第二个问题,这是你邮差截图中的问题。
注意:我在实际邮递员application中没有遇到任何此类问题。
当服务器等待chrome发送请求时,它无法为任何其他请求提供服务。为防止这种情况发生,请考虑使用asynchronous approach。