IMAP не является сложным протоколом, он основан на строках, и количество соответствующих команд ограничено, особенно если вы не хотите ничего, кроме проверки непрочитанных писем в папке входящих сообщений.
Так что довольно простопостроить клиент IMAP поверх System.Net.Sockets.TcpClient
.SSL / TLS немного сложен, но не так уж и плох.
Разговор с сервером IMAP происходит так:
Client: A001 command argument argument
Server: * response line 1
* response line 2
A001 OK response line 3
Где A001
- это тег команды, которыйдолжен идентифицировать команды.Часто это в виде счетчика с приращением (a1
, a2
, a3
, ...), но на самом деле это может быть что угодно.Сервер повторяет тег команды в последней строке своего ответа.
Пример диалога с сервером GMail IMAP (аутентификация не удалась, очевидно):
* OK Gimap ready for requests from 213.61.242.253 g189mb36880374lfe
a1 CAPABILITY
* CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 XYZZY SASL-IR AUTH=XOAUTH2 AUTH=PLAIN AUTH=PLAIN-CLIENTTOKEN AUTH=OAUTHBEARER AUTH=XOAUTH
a1 OK Thats all she wrote! g189mb36880374lfe
a2 LOGIN test test
a2 NO [AUTHENTICATIONFAILED] Invalid credentials (Failure)
a3 LOGOUT
* BYE Logout Requested g189mb36880374lfe
a3 OK Quoth the raven, nevermore... g189mb36880374lfe
Код Powershell, который сделал этоне слишком сложен:
using namespace System.IO;
using namespace System.Text;
using namespace System.Net.Sockets;
using namespace System.Net.Security;
using namespace System.Security.Cryptography.X509Certificates;
Set-StrictMode -Version 2.0
$DebugPreference = "Continue" # set to "SilentlyContinue" to hide Write-Debug output
$CRLF = "`r`n"
$server = "imap.gmail.com"
$port = 993
$username = "test"
$password = "test"
# connect to server
$client = [TcpClient]::new($server, $port)
$client.ReceiveTimeout = 2000 #milliseconds
# set up SSL stream, be lenient about the server's certificate
$acceptAnyCertificate = [RemoteCertificateValidationCallback] { $true }
$sslStream = [SslStream]::new($client.GetStream(), $false, $acceptAnyCertificate)
$sslStream.AuthenticateAsClient($server)
function StreamWrite {
param([Stream]$stream, [string]$command, [Encoding]$enc = [Encoding]::ASCII)
$data = $enc.GetBytes($command)
Write-Debug "> $($command.trim())"
$stream.Write($data, 0, $data.Length)
}
function StreamRead {
param([Stream]$stream, [int]$bufsize = 4*1KB, [Encoding]$enc = [Encoding]::ASCII)
$buffer = [byte[]]::new($bufsize)
$bytecount = $stream.Read($buffer, 0, $bufsize)
$response = $enc.GetString($buffer, 0, $bytecount)
Write-Debug "< $($response.trim())"
$response
}
# read server hello
$response = StreamRead $sslStream
StreamWrite $sslStream ("a1 CAPABILITY" + $CRLF)
$response = StreamRead $sslStream
# log in
StreamWrite $sslStream ("a2 LOGIN $username $password" + $CRLF)
$response = StreamRead $sslStream
# send mailbox commands...
# log out
StreamWrite $sslStream ("a3 LOGOUT" + $CRLF)
$response = StreamRead $sslStream
$sslStream.Close()
$client.Close()
Ваша команда почтового ящика, вероятно, будет простой select inbox
, на которую сервер отвечает набором информации, включая количество невидимых электронных писем (, например, можетбыть замеченным в Википедии ):
C: a002 select inbox
S: * 18 EXISTS
S: * FLAGS (\Answered \Flagged \Deleted \Seen \Draft)
S: * 2 RECENT
S: * OK [UNSEEN 17] Message 17 is the first unseen message
S: * OK [UIDVALIDITY 3857529045] UIDs valid
S: a002 OK [READ-WRITE] SELECT completed
Возможно, вам придется немного поэкспериментировать с вашим почтовым сервером, но должно быть легко выяснить необходимые детали.
Чтение Подключение к smtp.live.com с классом TcpClient , чтобы получить представление о том, как сделать STARTTLS
вместо SSL
, если этого требует ваш сервер.