Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用D,我将如何侦听传入的HTTP请求并响应它们?_Http_Sockets_D - Fatal编程技术网

使用D,我将如何侦听传入的HTTP请求并响应它们?

使用D,我将如何侦听传入的HTTP请求并响应它们?,http,sockets,d,Http,Sockets,D,使用D,我将如何侦听传入的HTTP流量并对其作出响应 例如(在伪代码中): 我知道还有很多,但我还没有找到很多关于响应传入http请求的资源 编辑: 我当前的尝试只产生了诸如“无法创建套接字:不允许操作”之类的异常。这可能意味着我做得正确,但只是收到了一条系统错误消息。这与侦听正常传入的TCP连接并响应它们是一样的: import std.socket; Socket s = new TcpSocket(AddressFamily.INET); s.bind(new Internet

使用D,我将如何侦听传入的HTTP流量并对其作出响应

例如(在伪代码中):

我知道还有很多,但我还没有找到很多关于响应传入http请求的资源

编辑:
我当前的尝试只产生了诸如“无法创建套接字:不允许操作”之类的异常。这可能意味着我做得正确,但只是收到了一条系统错误消息。

这与侦听正常传入的TCP连接并响应它们是一样的:

  import std.socket;
  Socket s = new TcpSocket(AddressFamily.INET);
  s.bind(new InternetAddress("0.0.0.0", 80));
  s.listen(8);
  while (true) {
    Socket conn=s.accept();
    //handle incoming message (I'm putting it in a task pool to handle ;) )
    taskPool.put(task!handleHttp(conn));
  }

使用包含接收http请求和发送响应的逻辑的
handleHttp(Socket)
作为http标准(您必须找到您自己)

标准库中当前没有http服务器。Adam Ruppe为Web工作提供了支持,但它目前不包括独立的Web服务器

下面的程序是一个简单的单线程基本HTTP服务器,用于教育 目的。生成有效的HTTP响应仍然取决于您;但至少是这样 解析标题,并根据标题的详细信息提供响应的机会 请求

import std.algorithm;
import std.conv;
import std.stdio;
import std.socket;
import std.string;

// usage: ./server port

void main(string[] args)
{
  enum BACKLOG = 8;
  ushort PORT = to!ushort(args[1]);
  Socket s    = new TcpSocket(AddressFamily.INET);
  s.bind(new InternetAddress("0.0.0.0", PORT));
  s.listen(BACKLOG);

  scope (exit) 
  { 
    s.shutdown(SocketShutdown.BOTH);
    s.close();
  }

  while (true)
  {
    debug writeln("waiting...");
    Socket conn = s.accept();
    scope (exit)  
    {
      conn.shutdown(SocketShutdown.BOTH);
      conn.close();
    }
    try
    {
      handleHttp(conn);
    }
    catch (Throwable e) 
    {
      stderr.writeln("thrown: ", e);
    }
  }    
}

void handleHttp(Socket conn)
{
  // Make a buffer big enough to read a full HTTP header. My approach here is to 
  // read the header in its entirety before proceeding. This isn't production
  // quality, but good enough for some applications.

  ubyte[8192] buf;  // big enough for some purposes...
  size_t position, headerEnd, len, newpos;

  // Receive the whole header before parsing it.
  while (true) 
  {
    len = conn.receive(buf[position..$]);

    if (len == 0)               // empty request
      return;

    newpos    = position + len;
    headerEnd = countUntil(buf[position..newpos], "\r\n\r\n");
    position  = newpos;

    if (headerEnd >= 0) 
      break;
  }

  // Anything beyond headerEnd+4 is part of the request body. For now, bail:
  // no POSTs or PUTs allowed. Feel free to remove the assert & implement them!
  assert (position-(headerEnd+4) == 0, 
          "Sorry, only content-free requests are supported.");

  // Now parse the header.
  auto lines          = splitter(buf[0..headerEnd], "\r\n");
  string request_line =  cast(string) lines.front; 
  lines.popFront;

  debug writeln(request_line);

  // a very simple Header structure.
  struct Pair 
  { 
    string key, value;

    this(ubyte[] line) 
    {
      auto tmp = countUntil(line, ": ");
      key       = cast(string) line[0..tmp]; // maybe down-case these?
      value     = cast(string) line[tmp+2..$];
    }
  }

  Pair[] headers;
  foreach(line; lines) 
    headers ~= Pair(line);

  auto tmp        = splitter(request_line, ' ');
  string method   = tmp.front; tmp.popFront;
  string url      = tmp.front; tmp.popFront;
  string protocol = tmp.front; tmp.popFront;

  debug writefln("%s, %s, %s", method, url, protocol);

  // Prepare a response, and send it

  string resp = join(["HTTP/1.1 200 OK", 
                      "Content-Length: 2",
                      "Content-Type: text/plain",
                      "Connection: close",
                      "",
                      "OK"],
                     "\r\n");

  conn.send(cast(ubyte[]) resp);
}
有一个名为的多线程(基于事件)Web服务器,它支持本地D脚本


<>我从未用过D脚本,只有用它运行的C++脚本。< /P>你有没有在端口80或其他低级端口上侦听的权限?尝试使用端口8080或其他不在限制范围内的端口。我正在尝试使用端口3000。我也试过8080和其他一些。
import std.algorithm;
import std.conv;
import std.stdio;
import std.socket;
import std.string;

// usage: ./server port

void main(string[] args)
{
  enum BACKLOG = 8;
  ushort PORT = to!ushort(args[1]);
  Socket s    = new TcpSocket(AddressFamily.INET);
  s.bind(new InternetAddress("0.0.0.0", PORT));
  s.listen(BACKLOG);

  scope (exit) 
  { 
    s.shutdown(SocketShutdown.BOTH);
    s.close();
  }

  while (true)
  {
    debug writeln("waiting...");
    Socket conn = s.accept();
    scope (exit)  
    {
      conn.shutdown(SocketShutdown.BOTH);
      conn.close();
    }
    try
    {
      handleHttp(conn);
    }
    catch (Throwable e) 
    {
      stderr.writeln("thrown: ", e);
    }
  }    
}

void handleHttp(Socket conn)
{
  // Make a buffer big enough to read a full HTTP header. My approach here is to 
  // read the header in its entirety before proceeding. This isn't production
  // quality, but good enough for some applications.

  ubyte[8192] buf;  // big enough for some purposes...
  size_t position, headerEnd, len, newpos;

  // Receive the whole header before parsing it.
  while (true) 
  {
    len = conn.receive(buf[position..$]);

    if (len == 0)               // empty request
      return;

    newpos    = position + len;
    headerEnd = countUntil(buf[position..newpos], "\r\n\r\n");
    position  = newpos;

    if (headerEnd >= 0) 
      break;
  }

  // Anything beyond headerEnd+4 is part of the request body. For now, bail:
  // no POSTs or PUTs allowed. Feel free to remove the assert & implement them!
  assert (position-(headerEnd+4) == 0, 
          "Sorry, only content-free requests are supported.");

  // Now parse the header.
  auto lines          = splitter(buf[0..headerEnd], "\r\n");
  string request_line =  cast(string) lines.front; 
  lines.popFront;

  debug writeln(request_line);

  // a very simple Header structure.
  struct Pair 
  { 
    string key, value;

    this(ubyte[] line) 
    {
      auto tmp = countUntil(line, ": ");
      key       = cast(string) line[0..tmp]; // maybe down-case these?
      value     = cast(string) line[tmp+2..$];
    }
  }

  Pair[] headers;
  foreach(line; lines) 
    headers ~= Pair(line);

  auto tmp        = splitter(request_line, ' ');
  string method   = tmp.front; tmp.popFront;
  string url      = tmp.front; tmp.popFront;
  string protocol = tmp.front; tmp.popFront;

  debug writefln("%s, %s, %s", method, url, protocol);

  // Prepare a response, and send it

  string resp = join(["HTTP/1.1 200 OK", 
                      "Content-Length: 2",
                      "Content-Type: text/plain",
                      "Connection: close",
                      "",
                      "OK"],
                     "\r\n");

  conn.send(cast(ubyte[]) resp);
}