fsockopen开打很慢的原因-完善DZ的dfopen函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
function  dfopen( $url $post  '' $limit  = 0,   $cookie  '' $bysocket  = FALSE,  $ip  '' $timeout  = 15,  $block  = TRUE) {
     $return  '' ;
     $uri  parse_url ( $url );
     $host  $uri [ 'host' ];
     $path  $uri [ 'path' ] ?  $uri [ 'path' ].( $uri [ 'query' ] ?  '?' . $uri [ 'query' ] :  '' ) :  '/' ;
     $port  = ! empty ( $uri [ 'port' ]) ?  $uri [ 'port' ] :  '' ;
     if (! $port ){
         $port  = ( $uri [ 'scheme' ] ==  'https' ) ? 80 : 80;
     }
     if ( $post ) { //post请求
         $post  = http_build_query( $post );
         $out  "POST $path HTTP/1.0\r\n" ;
         $out  .=  "Accept: */*\r\n" ;
         //$out .= "Referer: $boardurl\r\n";
         $out  .=  "Accept-Language: zh-cn\r\n" ;
         $out  .=  "Content-Type: application/x-www-form-urlencoded\r\n" ;
         $out  .=  "User-Agent: $_SERVER[HTTP_USER_AGENT]\r\n" ;
         $out  .=  "Host: $host\r\n" ;
         $out  .=  'Content-Length: ' . strlen ( $post ). "\r\n" ;
         $out  .=  "Connection: Close\r\n" ;
         $out  .=  "Cache-Control: no-cache\r\n" ;
         $out  .=  "Cookie: $cookie\r\n\r\n" ;
         $out  .=  $post ;       
     else  { //get请求
         $out  "GET $path HTTP/1.0\r\n" ;
         $out  .=  "Accept: */*\r\n" ;
         //$out .= "Referer: $boardurl\r\n";
         $out  .=  "Accept-Language: zh-cn\r\n" ;
         $out  .=  "User-Agent: $_SERVER[HTTP_USER_AGENT]\r\n" ;
         $out  .=  "Host: $host\r\n" ;
         $out  .=  "Connection: Close\r\n" ;
         $out  .=  "Cookie: $cookie\r\n\r\n" ;
     }
      
     $fp  = @ fsockopen (( $ip  $ip  $host ),  $port $errno $errstr $timeout );
     if (! $fp ) {
         return  false; //note $errstr : $errno \r\n
     else  {
         //集阻塞/非阻塞模式流,$block==true则应用流模式
         stream_set_blocking( $fp $block );
         //设置流的超时时间
         stream_set_timeout( $fp $timeout );
         @fwrite( $fp $out );
         //从封装协议文件指针中取得报头/元数据
         $status  = stream_get_meta_data( $fp );
  
         //timed_out如果在上次调用 fread() 或者 fgets() 中等待数据时流超时了则为 TRUE,下面判断为流没有超时的情况
         if (! $status [ 'timed_out' ])
         {
             while  (! feof ( $fp )) {
                 $header  = @ fgets ( $fp );
                 $findstr  'Content-Length:' ;
                 if ( strpos ( $header $findstr ) !== false){ //获取内容长度
                     $limit  intval ( substr ( $header strlen ( $findstr )));
                 }
                 if ( $header  ==  "\r\n"  ||   $header  ==  "\n" ) {
                     break ;
                 }
             }
             $stop  = false;
              
             //如果没有读到文件尾
             while (! feof ( $fp ) && ! $stop ) {
                 //看连接时限是否=0或者大于8192  =》8192  else =》limit  所读字节数
                 $data  fread ( $fp , ( $limit  == 0 ||  $limit  > 8192 ? 8192 :  $limit ));
                 $return  .=  $data ;
                 if ( $limit ) {
                     $limit  -=  strlen ( $data );
                     $stop  $limit  <= 0;
                 }
             }
         }
         @fclose( $fp );
         return  $return ;
     }
}

业务需要,使用fsockopen模拟get/post的请求去获取数据,
在网上找了下封装好的方法,看DZ封装的那个函数还不错,就拿来使用了。代码如下:有的地方我修改过了


开始测试了一下,就是运行会很慢,需要10几秒的时间才能运行完毕。
但是用file_get_contents的话,很快就能取到数据。
排查了一下,应该是对方的服务器保持活动链接,然后又因为我取数据的时候用到了
!feof($fp),这个地方跟那个指定的获取的长度有关,也就是$limit,如果这个值越大,
他就会一直找下去,只到找到换行符。
最好的办法就是再加个获取内容长度的代码,这样就避免的长时间的等待。
修改的代码主要是这一块

1
2
3
4
5
6
7
8
9
10
while  (! feof ( $fp )) {
     $header  = @ fgets ( $fp );
     $findstr  'Content-Length:' ;
     if ( strpos ( $header $findstr ) !== false){ //获取内容长度
         $limit  intval ( substr ( $header strlen ( $findstr )));
     }
     if ( $header  ==  "\r\n"  ||   $header  ==  "\n" ) {
         break ;
     }
}


OK,好了。测试通过了。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值