소켓 통신 프로그래밍하기 네트워크 프로그래밍의 가장 기초이자 핵심이 되는 것은 TCP/IP와 UDP라고 해도 과언이 아닐 것이다. 실제로 프로젝트에서 가장 많이 사용되는 프로그래밍 인터페이스가 TCP와 UDP이다. TCP나 UDP는 타 서버와의 연동할 때 유용하게 쓰인다. 서버의 정보를 가져올 때나 서버와 서버 사이에 정보를 교환할 때 사용한다. 실제로 프로젝트에서 쓰이는 예제를 한번 살펴보자. 해당 예제 코드는 특정 서비스를 진행하는 서버로 소켓을 보내서 해당 정보를 받아서 패킷을 처리하는 방식이다.
<?
$socket=socket_create(AF_INET,SOCK_DGRAM,SOL_UDP);
$remote_port=시스템포트;
$remote_host=“시스템아이피‘;
$kkk = socket_connect($socket,$remote_host,$remote_port);
$send_data="보낼데이터";
socket_send ($socket, $send_data, strlen($send_data), 0);
socket_recv($socket, $yyyy,4000,0)
echo("$yyyy");
?>
이 예제는 UDP 소켓을 이용하여 정보를 주고받는 것으로 socket_create() 함수로 소켓을 생성하고, socket_connect()으로 해당 서버와의 연결을 시도한다(socket_create() 함수에서 SOCK_DGRAM 파라미터는 비연결성 지향인 UDP를 위해서 설정해 준다. TCP라면 SOCK_STREAM 파라미터를 사용해야 한다). socket_send() 함수와 socket_recv() 함수를 이용해서 서버와 통신을 해서 해당 서버의 정보를 가져오는 방법이다. 코드는 아주 간결하게 보이나 유의해야 할 점이 있다. 만일 PHP 버전이 4.2.3 이전 버전이라면 socket_recv() 함수에서 오류가 날 것이다. 다음은 4.2.3의 news.txt에 나와 있는 변경안이다.
06 Sep 2002, Version 4.2.3
Modified socket_recv() behavior. [$r=socket_recv($sock, $buf, $len, $flags)]
이전의 socket_recv() 함수가 변경되었다는 말이다. 이전의 socket_recv() 함수를 살펴보면 파라미터가 하나 더 작다. 실제 PHP 엔진이 업그레이드될수록 소켓 함수에 대한 변동이 잦아지는데 매뉴얼을 살펴보아도 실험적인 함수임을 표기해놓고 있다. 자신의 PHP 엔진과 변경사항을 잘 구분하여 프로그래밍에 임하길 바란다. 다음과 같은 경고 화면을 볼 수 있을 것이다.
Warning : This function is EXPERIMENTAL. The behaviour of this function, the name of this function, and anything else documented about this function may change without notice in a future release of PHP. Use this function at your own risk. Warning : This function is currently not documented; only the argument list is available.
또한 소켓 프로그래밍에서 빼서는 안될 부분이 바로 에러 핸들링이다. 소켓통신은 연결을 기본으로 진행되는 것이 때문에(물론 UDP는 비연결지향이다) 대상 서버의 상태를 잘 파악해야 한다. 대상 서버의 상태를 살펴볼 수 있는 오류의 사항은 두 가지로 나눌 수 있다.
ꊱ 해당 서버는 기동되어 있으나 통신을 처리해 주는 프로세스(통신 프로그램)가 장애나 기동되지 않았을 때 ꊲ 해당 서버 자체가 장애나 기동되지 않았을 때
만일 앞의 UDP 코드에서 서버가 다운된 상황이라면 socket_send()를 호출해 대상 서버로 데이터를 보내고 나서(여기까지는 오류가 나지 않는다. UDP는 비연결 지향이기 때문이다) socket_recv() 함수에서 다음과 같은 오류가 나타날 것이다.
Warning: socket_recv() unable to read from socket [0]: 작업을 완료했습니다. in c:serversocket.php on line 24
이것은 실제로 socket_send()로 보냈지만 아무런 결과를 받지 못했을 때 나는 오류이다. 앞의 서버 상태일 때 나타날 수 있는 오류라고 할 수 있겠다. 이런 문제가 빈번하게 발생할 수 있기 때문에 반드시 개발자는 에러 핸들링에 대한 설계를 진행해야 한다. 앞과 같은 UDP 코드라면 2가지의 오류를 고려한 에러 핸들링을 추가하면 될 것이다.
<?
if(!@socket_recv($socket, $yyyy,4000,0) )
{
echo("
서버에 접속되지 않거나 프로그램이 동작하지 않습니다.");
exit;
}
?>
| |