PHP 네트워크 프로그래밍 샘플

Computer/Web Programming 2010. 4. 1. 17:26
뭔가를 좀 하다가 특정 서버에 TCP 패킷을 보낼 일이 있었다.
컴파일러도 없는 환경에서 C로 짜기는 영 어쩐지 싫고, 깔려있던 PHP로 어찌저찌 해보자는 맘을 가지고 PHP 네트워크 프로그래밍을 좀 찾다가 찾은 참조 소스랑..
짰던 소스랑.

1. 샘플
<?php
error_reporting(E_ALL);
echo "
TCP/IP Connection
\n";
/* Get the port for the WWW service. */
$service_port = getservbyname('www', 'tcp');
/* Get the IP address for the target host. */
$address = gethostbyname('www.example.com');
/* Create a TCP/IP socket. */
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket < 0) {
   echo "socket_create() failed: reason: " . socket_strerror($socket) . "\n";
} else {
   echo "OK.\n";
}
echo "Attempting to connect to '$address' on port '$service_port'...";
$result = socket_connect($socket, $address, $service_port);
if ($result < 0) {
   echo "socket_connect() failed.\nReason: ($result) " . socket_strerror($result) . "\n";
} else {
   echo "OK.\n";
}
$in = "HEAD / HTTP/1.1\r\n";
$in .= "Host: www.daum.net\r\n";
$in .= "Connection: Close\r\n\r\n";
$out = '';
echo "Sending HTTP HEAD request...";
socket_write($socket, $in, strlen($in));
echo "OK.\n";
echo "Reading response:\n\n";
while ($out = socket_read($socket, 2048)) {
   echo $out;
}
echo "Closing socket...";
socket_close($socket);
echo "OK.\n\n";
?>





2. 뭔가 짜다만 소스
<?php
$Host = "xxx.xxx.xxx.xx";
$Port = "10020";
/* Create a TCP/IP socket. */
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket < 0) {
   echo "socket_create() failed: reason: " . socket_strerror($socket) . "\n";
} else {
   echo "Olleh~! Connected.\n";
}
echo "Attempting to connect to '$Host' on port '$Port'...";
$result = socket_connect($socket, $Host, $Port);
if ($result < 0) {
   echo "socket_connect() failed.\nReason: ($result) " . socket_strerror($result) . "\n";
} else {
   echo "OK.\n";
}
/*
$socket2 = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket2 < 0) {
   echo "socket_create() failed: reason: " . socket_strerror($socket) . "\n";
} else {
   echo "Olleh~! Connected.\n";
}
echo "Attempting to connect to '$Host' on port '$Port'...";
$result = socket_connect($socket2, $ImanHost, 1053);
if ($result < 0) {
   echo "socket_connect() failed.\nReason: ($result) " . socket_strerror($result) . "\n";
} else {
   echo "OK.\n";
}
*/
$in=chr(1)."10".chr(242).chr(0).chr(0).chr(0).chr(135).chr(0).chr(0).chr(0)."I&bodytype=0&from=IMAN04/10dd3/0/imanBuddyService&svc=profilesvr&to=I08".chr(0).chr(0).chr(0)."6&cmd=profile&kid=3H00107555@company.co.kr&lparam=&version=1";
$out = '';
echo "Sending TCP request...";
if (socket_write($socket, $in, strlen($in)) <0 ) echo "Error.\n";
else echo "OK.\n\n";
echo "Reading response:\n\n";
while ($out = socket_read($socket, 4096)) {
   echo $out;
}
echo "Closing socket...";
socket_close($socket);
echo "OK.\n\n";
 
/*
Original Packet
00000000  01 31 30 F2 00 00 00 87  00 00 00 49 26 62 6F 64   .10..... ...I&bod
00000010  79 74 79 70 65 3D 30 26  66 72 6F 6D 3D 49 4D 41   ytype=0& from=IMA
00000020  4E 30 38 2F 31 30 37 39  64 2F 30 2F 69 6D 61 6E   N08/1079 d/0/iman
00000030  42 75 64 64 79 53 65 72  76 69 63 65 26 73 76 63   BuddySer vice&svc
00000040  3D 70 72 6F 66 69 6C 65  73 76 72 26 74 6F 3D 49   =profile svr&to=I
00000050  4D 41 4E 30 38 00 00 00  36 26 63 6D 64 3D 70 72   MAN08... 6&cmd=pr
00000060  6F 66 69 6C 65 26 6B 69  64 3D 33 48 30 30 31 30   ofile&ki d=3H0010
00000070  37 35 35 35 40 6B 74 2E  63 6F 2E 6B 72 26 6C 70   7555@company. co.kr&lp
00000080  61 72 61 6D 3D 26 76 65  72 73 69 6F 6E 3D 31      aram=&ve rsion=1

내가 보낸 아이들.
00000000  01 31 30 F2 00 00 00 87  00 00 00 49 26 62 6F 64   .10..... ...I&bod
00000010  79 74 79 70 65 3D 30 26  66 72 6F 6D 3D 49 4D 41   ytype=0& from=IMA
00000020  4E 30 38 2F 31 30 37 39  64 2F 30 2F 69 6D 61 6E   N08/1079 d/0/iman
00000030  42 75 64 64 79 53 65 72  76 69 63 65 26 73 76 63   BuddySer vice&svc
00000040  3D 70 72 6F 66 69 6C 65  73 76 72 26 74 6F 3D 49   =profile svr&to=I
00000050  4D 41 4E 30 38 2E 2E 2E  36 26 63 6D 64 3D 70 72   MAN08... 6&cmd=pr
00000060  6F 66 69 6C 65 26 6B 69  64 3D 33 48 30 30 31 30   ofile&ki d=3H0010
00000070  37 35 35 35 40 6B 74 2E  63 6F 2E 6B 72 26 6C 70   7555@company. co.kr&lp
00000080  61 72 61 6D 3D 26 76 65  72 73 69 6F 6E 3D 31      aram=&ve rsion=1

.10........I&bodytype=0&from=IMAN08/1079d/0/imanBuddyService&svc=profilesvr&to=IMAN08...6&cmd=profile&kid=3H00107555@company.co.kr&lparam=&version=1
01:31:30:F2:00:00:00:87:00:00:00:49:26:62:6F:64:79:74:79:70:65:3D:30:26:66:72:6F:6D:3D:49:4D:41:4E:30:38:2F:31:30:37:39:64:2F:30:2F:69:6D:61:6E:42:75:64:64:79:53:65:72:76:69:63:65:26:73:76:63:3D:70:72:6F:66:69:6C:65:73:76:72:26:74:6F:3D:49:4D:41:4E:30:38:00:00:00:36:26:63:6D:64:3D:70:72:6F:66:69:6C:65:26:6B:69:64:3D:33:48:30:30:31:30:37:35:35:35:40:6B:74:2E:63:6F:2E:6B:72:26:6C:70:61:72:61:6D:3D:26:76:65:72:73:69:6F:6E:3D:31
?10????????I&bodytype=0&from=IMAN08/1079d/0/imanBuddyService&svc=profilesvr&to=IMAN08???6&cmd=profile&kid=3H00107555@company.co.kr&lparam=&version=1
*/
 
?>

보안상 문제될(?) 부분을 약간씩 고치다보니 저대로 돌리면 당근 안돌아간다.
아무튼 잘 짜놓고서 콘솔에서 php xxx.php 하면 이쁘게 돌아간다.

요약하면..
1. PHP로 간단히 TCP 패킷 송수신 프로그램을 짤 수 있다는 것
2. 패킷 캡쳐링 했던 것과 텍스트로 같은 패킷을 보낼때는 캡쳐상의 . 이나 기타 공백 등 특수 아스키 코드가 눈에 보이는 것과 값이 다를 수 있다. 그래서 만들어서 송신하는 패킷도 테스트하여 잡아보고, 헥사코드로 다른 점이 발견되면 아래와 같이 string에 아스키 코드 실제값으로 이어붙여줄 필요가 있다.
$in=chr(1)."10".chr(242).chr(0).chr(0).chr(0).chr(135).chr(0).chr(0)...
3. PHP 프로그래밍은 쉽다 + 그래도 이건 너무 대충대충 짰다. ;