POP3 протокол с примерами

POP3 протокол с примерами

POP3 это протокол по которому мы можем получить почту с сервера, для подобной задачи, используется ещё протокол IMAP, но о нём я возможно напишу в будущем, когда столкнусь с ним. А для отправки почты используется как правило SMTP протокол, но речь здесь пойдёт о получении почты. Сначала немного теории.

Как работает POP3 протокол.

?так, согласно почтовому протоколу POP3, сервер вешается на порт 110 и слушает входящие соединения. Сервер это сноб – он никогда не начнёт диалог первым. Поэтому первыми с ним должны «заговорить» (подключиться) мы, используя TCP соединение. ? когда соединение установлено POP3 сервер посылает нам приглашение. Затем, пока соединение остаётся открытым происходит обмен данными.

В конце статьи пример простенького скрипта, а пока краткое описание. ?так, действующие лица: S: – сервер, С: - клиент.

Команды протокола POP3

Команды протокола POP3 состоят из ключевых слов, за которыми могут следовать аргументы например: DELE 1 - здесь мы ( т.е. клиент ) сообщили серверу, что мы помечаем 1 сообщение на удаление. ( Почему DELE, а не DELETE ? – читай ниже. )

Все команды серверу должны заканчиваться парой CRLF ( это, если писать скрипты, символы: \n – В Unix подобных системах и \r\n в форточках ).

Команды и их аргументы должны состоять из символов печатаемого диапазона ASCII.

Команда и её аргументы должны разделяться одним(!) пробелом.

Ключевое слово команды должно быть от 3 до 4 символов длиной, а её аргумент не может превышать 40 символов.

Согласно протоколу POP3, ответы сервера состоят из флага состояния – это:


  +OK  –  Всё хорошо.
  -ERR –  Всё плохо.

? ключевого слова, за которым может идти дополнительная информация, например:


  S:+OK vasya’s maildrop has 2 messages (320 octets)CRLF

Как видно выше, ответ сервера так же заканчивается парой CRLF

Пара CRLF ассоциируется у меня со словом «Приём» - это, как по рации: когда ты всё, что хотел, сказал и в конце говоришь слово «Приём», что бы собеседник понял, что теперь ты его слушаешь.

?ногда ответ сервера содержит несколько строк:


  С: LISTCRLF
  S: +OK 2 messages (320 octets)CRLF
  S: 1 120CRLF
  S: 2 200CRLF
  S: .CRLF

- В таком случае, если каждая строка, в соответствии с протоколом POP3 - заканчивается парой CRLF то, как нам понять, где конец ответа? В данном случае концом всего ответа нужно считать строку: .CRLF где точка - это символ ASCII с кодом 46 и знакомая нам пара CRLF.

APOP [имя][digest]

Эта команда передаёт POP3 серверу логин и зашифрованный пароль(digest). ?спользуется, когда мы хотим авторизоваться на сервере, и при этом не передавать пароль в открытом виде.

[имя] — строка, указывающая имя почтового ящика.

[digest] — временная метка, сконкатенированная с паролем, и зашифрованная по MD5-алгоритму.

Если эта команда поддерживается, метка времени получается при соединении с сервером.

USER [имя]

Отправляет имя пользователя.

[имя] — строка, указывающая имя пользователя ( почтового ящика ).

PASS [пароль]

Отправляет пароль пользователя.

[пароль] — пароль к почтовому ящика.

DELE [сообщение]

Помечает указанное сообщение на удаление. Помеченные сообщения, на самом деле, удаляются только после закрытия транзакции, после того, как прошла команда QUIT. Так же закрытие транзакций на серверах может происходить по истечении временного лимита, установленного сервером. Что бы этого не произошло можно посылать серверу пинги

[сообщение] — номер сообщения.

LIST [сообщение]

Если передать аргумент - номер сообщения, то сервер выдаёт инфу о запрашиваемом сообщении. ?наче, сервер выдаёт информацию про все сообщения, которые есть на почте. Кстати, сообщения, помеченные для удаления, не перечислятся.

[сообщение] — номер сообщения (необязательно).

NOOP

Это что то вроде пинга серверу, в случае доступности сервер всегда ответит +OK.

Можно посылать эту команду, время от времени, что бы сервер не закрыл соединения при длительном простое.

RETR [сообщение]

Получить сообщение с указанным номером.

[сообщение] — номер сообщения.

RSET

Откат транзакций в пределах текущего сеанса. К примеру, если вы случайно пометили сообщение на удаление, то можно убрать метки, послав команду RSET.

STAT

Получить количество сообщений в ящике, а так же ещё и размер, занимаемый этими сообщениями на сервере.

TOP

Получить заголовки указанного сообщения, и указанное количество первых строк сообщения. Эти данные вернуться, разделённые пустой строкой.

[сообщение] — номер сообщения.

[количество строк] — сколько строк нужно вывести.

?мя Аргументы Ограничения Возможные ответы
APOP
[имя] [digest]
Поддержка этой команды не гарантируется
* +OK maildrop has n message
* -ERR password suplied for [имя] is incorrect
USER
[имя]
* +OK name is a valid mailbox
* -ERR never heard of mailbox name
PASS
[пароль]
Работает после успешной передачи имени почтового ящика
* +OK maildrop locked and ready
* -ERR invalid password
* -ERR unable to lock maildrop
DELE
[сообщение]
Доступна после успешной идентификации
* +OK message deleted
* -ERR no such message
LIST
[сообщение]
Доступна после успешной идентификации
* +OK scan listing follows
* -ERR no such message
NOOP
Доступна после успешной идентификации
+OK
RETR
[сообщение]
Доступна после успешной идентификации
* +OK message follows
* -ERR no such message
RSET
Доступна после успешной идентификации
+OK
STAT
Доступна после успешной идентификации
+OK a b
TOP
[сообщение]
[количество строк]
Доступна после успешной идентификации
* +OK n octets
* -ERR no such message
QUIT
+OK

Состояния сеанса POP3

Согласно протоколу POP3, сеанс состоит из нескольких режимов:

AUTHORIZATION:

– ?меет место, когда мы соединились с сервером, и он отправил нам приглашение:

 
  S: <Сервер слушает порт 110>
  C: <подключается к серверу>
  S: +OK POP3 server ready
      

Здесь мы должны идентифицировать себя:


  C: APOP vasya c4c9334bac560ecc979e58001b3e22fb
  S: +OK vasya's maildrop has 2 messages (320 octets)
      

Здесь стоит пояснить, что команда APOP [имя] [digest], которую я опишу ниже, может и не поддерживаться. Тогда авторизация может происходить следующим образом, когда пароль передаётся открытым текстом:


  C: USER vasya
  S: +OK User accepted
  C: PASS vasinpass
  S: +OK Pass accepted
      

Если всё проходит успешно, наши отношения с сервером переходят в режим транзакции.

TRANSACTION:

- На данном этапе мы получаем информацию о состоянии нашего почтового ящика. Так же мы можем принять и отправить почту, а так же пометить письма на удаление. Завершить этот режим можно командой QUIT, получив её сервер, переходит к режиму UPDATE.

UPDATE:

На данном этапе сервер удаляет помеченные нами на удаление письма, в общем, освобождает ресурсы и закрывает соединение.

Стоит заметить, что у почтового сервера POP3 может существовать так называемый INACTIVITY AUTOLOGOUT таймер. Он должен иметь, по крайней мере, 10-минутный интервал. Это означает, что если мы не общаемся с сервером в течение этого интервала, сервак «огорчается» на нас, и автоматически закрывает соединение, не переходя при этом, в режим UPDATE.

Пример диалога с почтовым сервером POP3


  S: <Сервер ожидает входящих соединений на порту 110>
  C: <подключается к серверу>
  S:    +OK POP3 server ready <1896.697170952@dbc.mtview.ca.us>
  C:    APOP vasya c4c9334bac560ecc979e58001b3e22fb
  S:    +OK vasya's maildrop has 2 messages (320 octets)
  C:    STAT
  S:    +OK 2 320
  C:    LIST
  S:    +OK 2 messages (320 octets)
  S:    1 120
  S:    2 200
  S:    .
  C:    RETR 1
  S:    +OK 120 octets
  S:    <сервер передает сообщение 1>
  S:    .
  C:    DELE 1
  S:    +OK message 1 deleted
  C:    RETR 2
  S:    +OK 200 octets
  S:    <сервер передает сообщение 2>
  S:    .
  C:    DELE 2
  S:    +OK message 2 deleted
  C:    QUIT
  S:    +OK dewey POP3 server signing off (maildrop empty)
  C:  <закрывает соединение>
  S:  <продолждает ждать входящие соединения>

Как получить почту по POP3 из PHP

Конечно это самый простейший пример, просто что бы понять, как можно реализовать диалог с сервером. То что получается на выводе, я не привожу здесь. Вряд ли Вам будет интересна моя почта :)


  ob_implicit_flush();
  header('content-type: text/html; charset=windows-1251');
  
  // Определим пару CRLF:
  define('CRLF',"\r\n");
  
  // Функция для получения многострочного ответа:
  function getData($fp)
  {
      $data='';
      
      while ( !feof($fp) )
      {
          $line = trim(fgets($fp,1024));        
          if(trim($line) == '.') break;
          $data .= $line;
      }
      return $data;
  }
  
  // Открываем сокет
  $fp = fsockopen('pop.yandex.ru', 110, $errNo, $errStr, 10);
  print fgets($fp,1024).'<br />';
  
  // Посылаем Логин:
  fputs($fp,'USER vasya-pupkin'.CRLF);
  print fgets($fp,1024).'<br />';
  
  // Посылаем Пароль:
  fputs($fp,'PASS *****'.CRLF);
  print fgets($fp,1024).'<br />';
  
  // Запрашиваем письмо № 26
  fputs($fp,'RETR 26'.CRLF);
  print getData($fp);
  
  // Закрываем сессию:
  fputs($fp,'QUIT'.CRLF);

Добавить комментарий


Защитный код
Обновить



Кто на сайте
Сейчас 44 гостей онлайн