PHP中Libevent HTTP用戶端實現程式

來源:互聯網
上載者:User

php Libevent HTTP

 代碼如下 複製代碼

<?php
//請求完成回調
function _request_handler($req, $base) {
  global $pend_req;
  //echo __FUNCTION__, PHP_EOL;
 
  if (is_null($req)) {
    //echo "Timed out\n";
  } else {
    $response_code = $req->getResponseCode();
 
    if ($response_code == 0) {
      //echo "Connection refused\n";
    } elseif ($response_code != 200) {
      //echo "Unexpected response: $response_code\n";
    } else {
      //echo "Success: $response_code\n";
      /*
      $buf = $req->getInputBuffer();
      echo "Body:\n";
      while ($s = $buf->readLine(EventBuffer::EOL_ANY)) {
      echo $s, PHP_EOL;
      }
       */
    }
  }
  $pend_req--;
  //退出迴圈
  if (!$pend_req) {
    $base = $conn->getBase();
    $base->exit(NULL);
  }
  //釋放記憶體
  unset($req);
  unset($conn);
}
 
//$address = "www.111cn.net";
$pend_req = 0;
$port = 80;
//初始化event base
$base = new EventBase();
echo "Event method used: ", $base->getMethod(), PHP_EOL;
 //使用非同步DNS
$dns_base = new EventDnsBase($base, TRUE);
$f= fopen("./50000.txt","r");
while (!feof($f))
{
  $line = fgets($f);
  //echo $address;
  $address = trim($line);
  //建立http串連事件到base
  $conn = new EventHttpConnection($base, $dns_base, $address, $port);
  $conn->setTimeout(1);
  //佈建要求回調
  $req = new EventHttpRequest("_request_handler", $conn);
 
  $req->addHeader("Host", $address, EventHttpRequest::OUTPUT_HEADER);
  $req->addHeader("Content-Length", "0", EventHttpRequest::OUTPUT_HEADER);
  $conn->makeRequest($req, EventHttpRequest::CMD_GET, "/");
  $pend_req++;
}
fclose($f);
//事件主迴圈
$base->loop();
?>

c語言版,

 代碼如下 複製代碼

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <evhttp.h>
#include <event2/event.h>
#include <event2/http.h>
#include <event2/bufferevent.h>
typedef struct my_struct_s my_struct_t;
 
struct my_struct_s {
  struct evhttp_connection *conn;
  struct evhttp_request *req;
  struct evhttp_uri *uri;
  struct event *cleanup;
};
 
struct event_base *Base_Primary;
 
char *trimwhitespace(char *str)
{
  char *end;
 
  // Trim leading space
  while(isspace(*str)) str++;
 
  if(*str == 0)  // All spaces?
    return str;
 
  // Trim trailing space
  end = str + strlen(str) - 1;
  while(end > str && isspace(*end)) end--;
 
  // Write new null terminator
  *(end+1) = 0;
 
  return str;
}
 
void connection_free(int sock, short which, void *arg) {
  //printf("freeing connection!!! The socket's FD would have been closed when the HTTP request ended and the ->req object would have been free'd\n");
 
  // Get our structure object
  my_struct_t *myStruct = arg;
 
  // Cleanup our properties
  event_free(myStruct->cleanup);
  evhttp_connection_free(myStruct->conn);
  evhttp_request_free(myStruct->req);
  evhttp_uri_free(myStruct->uri);
 
  // Free our custom structure
  free(myStruct);
}
 
void http_request_done(struct evhttp_request *req, void *arg){
 
  // Get our custom struct
  my_struct_t *myStruct = arg;
 
  // Setup our timeout information (we delay 5 seconds)
  struct timeval Timeout;
  Timeout.tv_sec = 0;
  Timeout.tv_usec = 0;
 
  // Add this structure to our cleanup base to be cleaned up synchronously
  // TODO: Probably not the best way to cleanup and event, but it'l work for the purposes of illustration.
  // This way would ensure no race conditions exist, but it's probably not the most efficient depending on how many requests, etc we're dealing with.
  myStruct->cleanup = evtimer_new(Base_Primary, connection_free, (void *)myStruct);
  evtimer_add(myStruct->cleanup, &Timeout);
 
  //printf("http_request_done, we put our custom strucutre into a cleanup event to be freed!\n");
}
 
int http_req(char *uri) {
 
  // Allocate our custom struture
  my_struct_t *myStruct = malloc(sizeof(my_struct_t));
 
  // Create our EVHTP connection and request
  myStruct->uri = evhttp_uri_parse(uri);
  myStruct->conn = evhttp_connection_base_new(Base_Primary, NULL, uri, 80);
  myStruct->req = evhttp_request_new(http_request_done, myStruct);
  evhttp_add_header(evhttp_request_get_output_headers(myStruct->req), "Host", "localhost");
  evhttp_add_header(evhttp_request_get_output_headers(myStruct->req), "Connection", "close");
  evhttp_make_request(myStruct->conn, myStruct->req, EVHTTP_REQ_GET, uri);
  evhttp_connection_set_timeout(myStruct->req->evcon, 2);
  return 1;
}
 
 
// Define our primary function
int main(int argc, char *argv[]) {
 
  // Initialize our bases
  Base_Primary = event_base_new();
 
  char filename[] = "/tmp/50000.txt"; //檔案名稱
  FILE *fp;
  char StrLine[1024];             //每行最大讀取的字元數
  char *host;
  if((fp = fopen(filename,"r")) == NULL) //判斷檔案是否存在及可讀
  {
    printf("error!");
    return -1;
  }
 
  while (!feof(fp))
  {
    fgets(StrLine,1024,fp);  //讀取一行
    host = StrLine;
    host = trimwhitespace(host);
    //printf("%s", host); //輸出
    http_req(host);
  }
  fclose(fp); 
 
  //
  //event_base_loop(Base_Primary);
  event_base_dispatch(Base_Primary);
 
  // Free our primary base
  event_base_free(Base_Primary);
  return 1;
}

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.