글쎄, 실제로는 PHP로 POP3 서버를 작성하는 것이 가능하다는 것을 보여주기 위해 여기에 있습니다. 서버는 인증을하지 않습니다. 그것은 계속해서 동일한 메시지를 계속해서 계속해서 보내고 있습니다. 그러나 그것은 효과적이다. Thunderbird는 메시지를 검색 할 수있었습니다. 전혀 쓸모가 없지만 멋지다.
내 설정은 PHP 5.2가 설치된 Windows에서 Apache 2입니다.
<?php
// echo something so fopen() would return
header("Content-type: text/plain");
echo "OK\n";
flush();
// listen for incoming connection
$listen_socket = socket_create_listen(110, 1);
$r = $w = $e = array($listen_socket);
$n = socket_select($r, $w, $e, 120);
$client_socket = ($n == 1) ? socket_accept($listen_socket) : null;
socket_close($listen_socket);
// spawn copy of myself
$internal_url = "http://{$_SERVER['HTTP_HOST']}:{$_SERVER['SERVER_PORT']}{$_SERVER['SCRIPT_NAME']}";
$stream_context_options = array (
'http' => array (
'method' => 'GET',
'timeout' => 1
)
);
$context = stream_context_create($stream_context_options);
if($f = fopen($internal_url, "rb", 0, $context)) {
fclose($f);
}
if(!$client_socket) {
// timed out
exit;
}
// start handling the session
$read_buffer = "";
$write_buffer = "+OK POP3 server ready\r\n";
$active = true;
$messages = array(
"From: [email protected]\r\nSubject: This is a test\r\n\r\nHello world!\r\n"
);
$idle_start = time();
while(true) {
$r = $w = $e = array($client_socket);
$n = socket_select($r, $w, $e, 60);
if($n) {
if($r) {
// read from the socket
$read_buffer .= socket_read($client_socket, 128);
$idle_start = time();
}
if($w) {
if($write_buffer) {
// write to the socket
$written = socket_write($client_socket, $write_buffer);
$write_buffer = substr($write_buffer, $written);
$idle_start = time();
} else if($active) {
$now = time();
$idle_time = $now - $idle_start;
if($idle_time > 10) {
// exit if nothing happened for 10 seconds
break;
} else if($idle_time > 2) {
// start napping when the client is too slow
sleep(1);
}
} else {
break;
}
}
if($e) {
break;
}
if($read_buffer) {
if(preg_match('/(.*?)(?:\s+(.*?))?[\r\n]+/', $read_buffer, $matches)) {
$read_buffer = substr($read_buffer, strlen($matches[0]));
$command = $matches[1];
$argument = $matches[2];
switch($command) {
case 'USER':
$username = $argument;
$write_buffer .= "+OK $username is welcome here\r\n";
break;
case 'PASS':
$message_count = count($messages);
$write_buffer .= "+OK mailbox has $message_count message(s)\r\n";
break;
case 'QUIT':
$write_buffer .= "+OK POP3 server signing off\r\n";
$active = false;
break;
case 'STAT':
$message_count = count($messages);
$mailbox_size = 0;
foreach($messages as $message) {
$mailbox_size += strlen($message);
}
$write_buffer .= "+OK $message_count $mailbox_size\r\n";
break;
case 'LIST':
$start_index = (int) $argument;
$message_count = count($messages) - $start_index;
$total_size = 0;
for($i = $start_index; $i < count($messages); $i++) {
$total_size += strlen($messages[$i]);
}
$write_buffer .= "+OK $message_count messages ($total_size octets)\r\n";
for($i = $start_index; $i < count($messages); $i++) {
$message_id = $i + 1;
$message_size = strlen($messages[$i]);
$write_buffer .= "$message_id $message_size\r\n";
}
$write_buffer .= ".\r\n";
break;
case 'RETR':
$message_id = (int) $argument;
$message = $messages[$message_id - 1];
$message_size = strlen($message);
$write_buffer .= "+OK $message_size octets\r\n";
$write_buffer .= "$message\r\n";
$write_buffer .= ".\r\n";
break;
case 'DELE':
$write_buffer .= "+OK\r\n";
break;
case 'NOOP':
$write_buffer .= "+OK\r\n";
break;
case 'LAST':
$message_count = count($messages) - $start_index;
$write_buffer .= "+OK $message_count\r\n";
break;
case 'RSET':
$write_buffer .= "+OK\r\n";
break;
default:
$write_buffer .= "-ERR Unknown command '$command'\r\n";
}
}
}
} else {
break;
}
}
?>
PHP에서는이 구현이있을 수 있지만, 신의 사랑이 있다면 그것을 사용하지 마십시오! 쉘 스크립트 외에도, PHP는 내가 이것을 할 수있는 최악의 언어에 관한 것입니다. 웹 개발자가 이해할 수있는 언어로 뭔가를 원한다면 Node.js를 살펴보십시오. – DaveRandom
@DaveRandom, 네가 맞다. 그러나 내 앱은 PHP를 사용하며 Windows Azure 플랫폼에서 제공하는 옵션에 의해서도 제한을 받는다. –
음 POP3와 IMAP는 특별히 복잡한 프로토콜이 아니기 때문에 (지원하고자하는 것에 따라 다름) PHP에서 매우 쉽게 구현 될 수 있습니다.하지만 스레딩을 지원하지 않고 프로세스 포킹도 지원하지 않기 때문에 병행 성은 PHP에서 큰 문제입니다. . err ... 글쎄, 친절하고 말하기 도전 * Windows에서 구현하자. 또한 효율성면에서 이것은 충격적 일 것입니다. Node.js를 설치할 수있는 방법이 있습니까? 구글 둘러보기 나는 이미 사용하기 쉬운 API로 구현 된 2 개의 POP3와 1 개의 IMAP 서버를 발견했다. – DaveRandom