我想创建一个侦听端口443的TCP服务器,以便它可以接收HTTP请求并回发。
现在我正在使用Apache& PHP以正常方式执行此操作,但是可以在没有Web服务器的情况下执行此操作吗?
例如,我在C#.NET中构建了一个传统的TCP / IP客户端/服务器应用程序。是否可以使用此实现来处理HTTP请求而不是使用Web服务器?
答案 0 :(得分:3)
在最低级别,您可以使用HTTP侦听器类执行此操作。
http://geekswithblogs.net/Nitin/archive/2008/06/22/using-the-http-listener-class.aspx
我曾经写过类似uni项目的东西,所以如果你有任何特别的问题,我可以找代码。
如果你想要更高一些,你可能会考虑使用网络服务。
这是我的代码的一部分......看看你能用它做什么。 :
IPAddress address = IPAddress.Parse("127.0.0.1");
IPEndPoint port = new IPEndPoint(address, 9999); //port 9999
TcpListener listener = new TcpListener(port);
listener.Start();
Console.WriteLine("--Server loaded--");
while (true) //loop forever
{
Console.WriteLine("Waiting for New Client");
Socket sock = listener.AcceptSocket();
byte[] buffer = new byte[32];
string incomingMessage="";
//read:
while (sock.Available > 0)
{
int gotBytes = sock.Receive(buffer);
incomingMessage += Encoding.ASCII.GetString(buffer, 0, gotBytes);
}
//debugging:
//Console.WriteLine(incomingMessage);
//Now check whether its a GET or a POST
if (incomingMessage.ToUpper().Contains("POST") && incomingMessage.ToUpper().Contains("/DOSEARCH")) //a search has been asked for
{
Console.WriteLine("Query Has Been Received");
//extracting the post data
string htmlPostData = incomingMessage.Substring(incomingMessage.IndexOf("songName"));
string[] parameters = htmlPostData.Split('&');
string[] inputs = new string[5];
for (int i=0; i<parameters.Length; i++)
{
inputs[i] = (parameters[i].Split('='))[1];
inputs[i] = inputs[i].Replace('+',' ');
}
...
byte[] outbuffer = Encoding.ASCII.GetBytes(answerPage.ToString());
sock.Send(outbuffer);
Console.WriteLine("Results Sent");
sock.Close();
答案 1 :(得分:1)
此项目可帮助您从头开始创建Web服务器:MiniHttpd: an HTTP web server library使用纯TCP / IP
但是我没有处理许多不必要的细节,比如解析头文件,压缩,身份验证,ssl等。我会使用内置的HttpListener类。
这是一个简化的(但工作)多线程WebServer
void CreateWebServer()
{
HttpListener listener = new HttpListener();
listener.Prefixes.Add("http://*:8080/");
listener.Start();
new Thread(
() =>
{
while (true)
{
HttpListenerContext ctx = listener.GetContext();
ThreadPool.QueueUserWorkItem((_) => ProcessRequest(ctx));
}
}
).Start();
}
void ProcessRequest(HttpListenerContext ctx)
{
string responseText = "Hello";
byte[] buf = Encoding.UTF8.GetBytes(responseText);
Console.WriteLine(ctx.Request.Url);
ctx.Response.ContentEncoding = Encoding.UTF8;
ctx.Response.ContentType = "text/html";
ctx.Response.ContentLength64 = buf.Length;
ctx.Response.OutputStream.Write(buf, 0, buf.Length);
ctx.Response.Close();
}
修改强>
我稍微更改了服务器以使其托管 RESTful WebService (MyService
)。它将结果返回为Json。您可以将其称为http://localhost:8080/?method=Calc&i=5&j=4
(为简单起见,我省略了许多错误检查)
public class MyService
{
public Result Calc(int i, int j)
{
return new Result() { Addition = i + j, Multiplication = i * j };
}
}
public class Result
{
public int Addition { set; get; }
public int Multiplication { set; get; }
}
void CreateWebServer()
{
MyService service = new MyService();
HttpListener listener = new HttpListener();
listener.Prefixes.Add("http://*:8080/");
listener.Start();
new Thread(
() =>
{
while (true)
{
HttpListenerContext ctx = listener.GetContext();
ThreadPool.QueueUserWorkItem((_) => ProcessRequest(ctx,service));
}
}
).Start();
}
void ProcessRequest(HttpListenerContext ctx,MyService service)
{
try
{
string responseText = Execute(ctx, service);
byte[] buf = Encoding.UTF8.GetBytes(responseText);
ctx.Response.ContentEncoding = Encoding.UTF8;
ctx.Response.ContentType = "application/json";
ctx.Response.ContentLength64 = buf.Length;
ctx.Response.OutputStream.Write(buf, 0, buf.Length);
}
catch
{
ctx.Response.StatusCode = (int) HttpStatusCode.NotFound;
}
ctx.Response.Close();
}
string Execute(HttpListenerContext ctx, MyService service)
{
System.Collections.Specialized.NameValueCollection nv = HttpUtility.ParseQueryString(ctx.Request.Url.Query);
MethodInfo mi = service.GetType().GetMethod(nv["method"]);
object[] parameters = mi.GetParameters()
.Select(pi => Convert.ChangeType(nv[pi.Name], pi.ParameterType))
.ToArray();
return JsonConvert.SerializeObject(mi.Invoke(service, parameters));
}