테스트 사이트 - 개발 중인 베타 버전입니다

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

토루크막토 9개월 전 조회 1,401

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

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;

 

전체소스---

</p>

<p>    function post($host,$query,$method='POST') {

        $ref_url = ($_SERVER["HTTPS"])?"<a href="https://":"http://";" target="_blank" rel="noopener noreferrer">https://":"http://";</a>

        $ref_url .= $_SERVER['HTTP_HOST'];

        //echo $host;

        $url = parse_url($host);

        if(!$url['scheme']) {

            $host = "<a href="http://$host";" target="_blank" rel="noopener noreferrer">http://$host";</a>

            $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";</p>

<p>        <strong><span style="color:#e74c3c;">$h=stream_socket_client($host_url);

        fwrite($h,$post);</span></strong>

        for($a=0,$r='';!$a;) {

            <strong><span style="color:#e74c3c;">$b=fread($h,8192);</span></strong>

            $r.=$b;

            $a=(($b=='')?1:0);

        }

        <span style="color:#e74c3c;"><strong>fclose($h);</strong></span>

        return $r;

    }</p>

<p>

 

 

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

댓글을 작성하려면 로그인이 필요합니다.

답변 3개

채택된 답변
+20 포인트
glitter0gim
9개월 전

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)로 루프를 종료하도록 수정.

로그인 후 평가할 수 있습니다

답변에 대한 댓글 2개

토루크막토
8개월 전
정말 감사드립니다!!!
답변주신대로 수정하니 경고가 사라지고 문자메시지도 잘 들어 옵니다!!
복 많이 받으세요!
g
glitter0gim
8개월 전
구글링하며 저도 한 수 배워갑니다.
^^ 행복하세요!

댓글을 작성하려면 로그인이 필요합니다.

R
9개월 전

stream_socket_client 부분을 수정해보세요.

</p>

<p>    $context = stream_context_create([</p>

<p>        'ssl' => [</p>

<p>            'verify_peer' => false,</p>

<p>            'verify_peer_name' => false,</p>

<p>        ]</p>

<p>    ]);</p>

<p>    $h = stream_socket_client($host_url, $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $context);</p>

<p>

로그인 후 평가할 수 있습니다

답변에 대한 댓글 1개

토루크막토
8개월 전
답변 감사드립니다.
코드를 그대로 붙여보았는데
똑같은 줄 똑같은 경고 메시지가 나옵니다.

댓글을 작성하려면 로그인이 필요합니다.

9개월 전

https://sir.kr/qa/482362

 

==>  ./common.php 에 

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

로그인 후 평가할 수 있습니다

답변에 대한 댓글 1개

토루크막토
9개월 전
답변 감사합니다. 말씀대로 한줄 추가 했더니 일단 에러메시지는 안나오네요^^
근본적인 수정법을 알고 싶긴한데 당장 에러메시지가 안나오니 다행이긴 합니다.
감사합니다.

댓글을 작성하려면 로그인이 필요합니다.

답변을 작성하려면 로그인이 필요합니다.

로그인