stream_socket_client() 경고에 대한 수정을 하고 싶습니다.

stream_socket_client() 경고에 대한 수정을 하고 싶습니다.

QA

stream_socket_client() 경고에 대한 수정을 하고 싶습니다.

답변 3

본문

아래의 소스는 온라인 문의가 들어왔을 때 관리자에게 문자를 보내는 코드중 일부입니다.

php 5인 서버를 사용할 때는 에러메세지가 나오지 않았는데

php 7인 서버를 사용중인 지금은 에러메시지가 나옵니다. (이전 서버와  현서버의 차이가 php 버전뿐이라 이렇게 짐작하고 있습니다.)

 

이  코드를 사용하면 아래의 소스중 빨간 색 라인에서 에러가 나오는데 어떻게 수정해야할지 

고수님들에게 도움을 요청드립니다.

 

참고로 에러메세지는 나오는데 문자메세지의 발송은 잘 되고 있습니다.

 

Warning: stream_socket_client(): php_network_getaddresses: getaddrinfo failed: Name or service not known in /home/cunet/public_html/bbs/online_update.php on line 115

 

Warning: stream_socket_client(): unable to connect to ssl://www.k-db.kr:20443 (php_network_getaddresses: getaddrinfo failed: Name or service not known) in /home/cunet/public_html/bbs/online_update.php on line 115

 

Warning: fwrite() expects parameter 1 to be resource, bool given in /home/cunet/public_html/bbs/online_update.php on line 116

 

Warning: fread() expects parameter 1 to be resource, bool given in /home/cunet/public_html/bbs/online_update.php on line 118

 

Warning: fclose() expects parameter 1 to be resource, bool given in /home/cunet/public_html/bbs/online_update.php on line 122

 

--- 에러가 나는 부분 ---

        $h=stream_socket_client($host_url);
        fwrite($h,$post);

        for($a=0,$r='';!$a;) {
            $b=fread($h,8192);
            $r.=$b;
            $a=(($b=='')?1:0);
        }
        fclose($h);
        return $r;

 

전체소스---


    function post($host,$query,$method='POST') {
        $ref_url = ($_SERVER["HTTPS"])?"https://":"http://";
        $ref_url .= $_SERVER['HTTP_HOST'];
        //echo $host;
        $url = parse_url($host);
        if(!$url['scheme']) {
            $host = "http://$host";
            $url = parse_url($host);
        }
        if($url['scheme']=="https") $host_url = "ssl://$url[host]";
        else $host_url = "tcp://$url[host]";
        if($url['port']) $host_url .= ":$url[port]";
        elseif($url['scheme']=="https") $host_url .= ":443";
        else $host_url .= ":80";
        
        if($url['query']==NULL) $path = $url['path'];
        else $path = "$url[path]?$url[query]";
        
        $post="$method $path HTTP/1.1\r\nHost: $url[host]\r\nReferer: $ref_url\r\nContent-type: application/x-www-form-urlencoded\r\n${others}User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36\r\nContent-length: ".strlen($query)."\r\nConnection: close\r\n\r\n$query";
        $h=stream_socket_client($host_url);
        fwrite($h,$post);
        for($a=0,$r='';!$a;) {
            $b=fread($h,8192);
            $r.=$b;
            $a=(($b=='')?1:0);
        }
        fclose($h);
        return $r;
    }

 

 

미리 감사드립니다. (^^)(__)

이 질문에 댓글 쓰기 :

답변 3

PHP 7에서는 stream_socket_client() 사용 시

도메인 이름 확인 및 네트워크 주소 변환 문제로 인해

php_network_getaddresses: getaddrinfo failed 오류가 발생할 수 있음.

- 네트워크 문제,

- 도메인 네임 서버(DNS) 해석 문제,

- stream_socket_client()의 오류 처리 부족 등의 문제일 가능성이 있음.

 

※ 수정 방안 :

*에러 핸들링 추가: stream_socket_client()의 반환값이 false일 경우 예외를 던지도록 수정.

*타임아웃 설정: stream_socket_client() 호출 시 timeout 값을 명시하여

  네트워크 문제를 줄임.

*에러 출력: stream_socket_client()의 error_message를 받아 로깅.

*DNS 확인: gethostbyname()을 사용하여 호스트 주소를 직접 확인하고,

  IP가 반환되지 않으면 오류를 출력.

 

※ 코드에서 stream_socket_client() 호출 전 도메인 주소가 올바르게 변환되었는지 확인하고,

실패할 경우 적절한 오류 메시지를 반환하도록 개선 함.

function post($host, $query, $method = 'POST') {
    $ref_url = ($_SERVER["HTTPS"]) ? "https://" : "http://";
    $ref_url .= $_SERVER['HTTP_HOST'];

    $url = parse_url($host);
    if (!$url['scheme']) {
        $host = "http://$host";
        $url = parse_url($host);
    }

    if ($url['scheme'] == "https") {
        $host_url = "ssl://$url[host]";
        $port = isset($url['port']) ? $url['port'] : 443;
    } else {
        $host_url = "tcp://$url[host]";
        $port = isset($url['port']) ? $url['port'] : 80;
    }
    $host_url .= ":$port";

    if (empty($url['query'])) {
        $path = $url['path'];
    } else {
        $path = "$url[path]?$url[query]";
    }

    $post = "$method $path HTTP/1.1\r\n"
          . "Host: $url[host]\r\n"
          . "Referer: $ref_url\r\n"
          . "Content-type: application/x-www-form-urlencoded\r\n"
          . "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36\r\n"
          . "Content-length: " . strlen($query) . "\r\n"
          . "Connection: close\r\n\r\n"
          . $query;

    // 호스트의 IP 변환 및 확인
    $ip = gethostbyname($url['host']);
    if ($ip == $url['host']) {
        return "Error: Could not resolve host: " . $url['host'];
    }

    // 타임아웃 및 에러 핸들링 추가
    $errstr = "";
    $errno = 0;
    $h = @stream_socket_client($host_url, $errno, $errstr, 10); // 10초 타임아웃 설정

    if (!$h) {
        return "Error: stream_socket_client() failed - $errstr ($errno)";
    }

    fwrite($h, $post);
    $r = "";
    while (!feof($h)) {
        $r .= fread($h, 8192);
    }
    fclose($h);
    return $r;
}

*수정 코드의 주요 개선 사항 :

- stream_socket_client() 호출 전에 gethostbyname($url['host'])를 사용하여

  도메인 해석이 가능한지 확인.

- 도메인 해석이 실패할 경우 오류 메시지를 반환하여 추가적인 문제를 방지.

- stream_socket_client()의 timeout을 10초로 설정하여,

  응답이 지연될 경우 무한 대기하지 않도록 개선.

- stream_socket_client() 호출 시 발생하는 errno, errstr을 받아서 에러 메시지를 출력.

- @ 연산자를 사용하여 경고를 억제하고, 대신 직접 if (!$h) 조건으로 에러 메시지를 처리.

- 기존 코드에서 $b == ''을 검사하는 대신, 더 안정적인 feof($h)로 루프를 종료하도록 수정.

https://sir.kr/qa/482362

 

==>  ./common.php 에 

  ini_set('display_errors', '0');  추가하면 일단 안 나올 겁니다.

stream_socket_client 부분을 수정해보세요.


    $context = stream_context_create([
        'ssl' => [
            'verify_peer' => false,
            'verify_peer_name' => false,
        ]
    ]);
    $h = stream_socket_client($host_url, $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $context);
답변을 작성하시기 전에 로그인 해주세요.
QA 내용 검색
질문등록
전체 892
© SIRSOFT
현재 페이지 제일 처음으로