Форум: "Сети";
Текущий архив: 2007.04.22;
Скачать: [xml.tar.bz2];
ВнизНе посылается письмо размером больше 6 кб Найти похожие ветки
← →
FFx01 © (2006-07-27 06:47) [0]Пытаюсь выслать сообщение(c аттачем) на e-mail, сообщение посылается, но не больше 6 кб. Как можно выслать сообщение больше этого кол-ва?
Вот примерная процедура посылки сообщения
///--------------------------------------------
uses winsock;
procedure mys(str: String);
var
I: Integer;
begin
for I:=1 to Length(str) do if send(sock,str[I],1,0)=SOCKET_ERROR then exit;
end;
begin
MySmtp:="87.249.30.162";
WSAStartUp(257, wsadata);
sock:=socket(AF_INET,SOCK_STREAM,IPPROTO_IP);
sin.sin_family := AF_INET;
htons(25);
sin.sin_port := htons(25);
iaddr:=inet_addr(PChar(MySmtp));
sin.sin_addr.S_addr:=iaddr;
connect(sock,sin,sizeof(sin));
Mys("HELO world"+#13+#10);
Mys("MAIL FROM: user@mail.ru"+#13+#10);
Mys("RCPT TO: sender@nxt.ru"+#13+#10);
Mys("DATA"+#13+#10);
Mys("MIME-Version: 1.0"+#13+#10);
Mys("To: sender@nxt.ru"+#13+#10);
Mys("From: user@mail.ru"+#13+#10);
Mys("Subject: hello world"+#13+#10);
Mys("Date: [e.g Tue, 11 Dec 2002 11:10:00 -0400]"+#13+#10);
Mys("Content-Type: application/octet-stream; name="file.txt""+#13+#10);
Mys("Content-Type: text/plain; charset=koi8-r Content-Transfer-Encoding: 8bit"+#13+#10);
Mys("Content-Disposition: attachment; filename="file.txt""+#13+#10);
Mys(""+#13+#10);
//--------------------------------
fName := "text.txt";
AssignFile(f, fName);
Reset(f);
{$I+}
while not EOF(f) do
begin
readln(f, bufer);
Mys(bufer+#13#10);
end;
CloseFile(f);
//----------------------------
Mys("."+#13+#10);
Mys("QUIT"+#13+#10);
closesocket(sock);
end.
← →
Сергей М. © (2006-07-27 11:09) [1]Пробуй так:
procedure WSACheckResult(Value: Boolean);
begin
if not Value then
raise Exception.Create("ErrorCode " + IntToStr(WSAGetLastError));
end;
procedure mys(str: String);
var
i, BytesToSend, BytesSent: Integer;
begin
BytesToSend := Length(Str);
i := 1;
while BytesToSend > 0 do begin
BytesSent := send(sock, str[i], BytesToSend, 0);
WSACheckResult(BytesSent <> SOCKET_ERROR);
Dec(BytesToSend, BytesSent);
Inc(i, BytesSent);
end;
end;
...
var
Option: Boolean;
...
MySmtp:="87.249.30.162";
WSAStartUp(257, wsadata);
sock:=socket(AF_INET,SOCK_STREAM,IPPROTO_IP);
WSACheckResult(sock <> INVALID_SOCKET);
try
sin.sin_family := AF_INET;
sin.sin_port := htons(25);
iaddr:=inet_addr(PChar(MySmtp));
sin.sin_addr.S_addr:=iaddr;
Option := True;
WSACheckResult(SetSockOpt(sock, SOL_SOCKET, SO_LINGER, Option, SizeOf(Option)) <> SOCKET_ERROR);
WSACheckResult(connect(sock,sin,sizeof(sin)) <> SOCKET_ERROR);
Mys("HELO world"+#13+#10);
Mys("MAIL FROM: user@mail.ru"+#13+#10);
Mys("RCPT TO: sender@nxt.ru"+#13+#10);
Mys("DATA"+#13+#10);
Mys("MIME-Version: 1.0"+#13+#10);
Mys("To: sender@nxt.ru"+#13+#10);
Mys("From: user@mail.ru"+#13+#10);
Mys("Subject: hello world"+#13+#10);
Mys("Date: [e.g Tue, 11 Dec 2002 11:10:00 -0400]"+#13+#10);
Mys("Content-Type: application/octet-stream; name="file.txt""+#13+#10);
Mys("Content-Type: text/plain; charset=koi8-r Content-Transfer-Encoding: 8bit"+#13+#10);
Mys("Content-Disposition: attachment; filename="file.txt""+#13+#10);
Mys(""+#13+#10);
//--------------------------------
fName := "text.txt";
AssignFile(f, fName);
Reset(f);
{$I+}
while not EOF(f) do
begin
readln(f, bufer);
Mys(bufer+#13#10);
end;
CloseFile(f);
//----------------------------
Mys("."+#13+#10);
Mys("QUIT"+#13+#10);
finally
CloseSocket(sock);
end;
end.
← →
FireMan_Alexey © (2006-07-28 13:53) [2]А ты бинарный файл посылаеш или текстовый и выражение
readln(f, bufer);
Mys(bufer+#13#10); - это зачем если файл бинарный
размер буфера?
Может так?
while not EOF(f) do
begin
readln(f, bufer);
Mys(bufer);
end;
Mys(#13#10);
CloseFile(f);
← →
Slym © (2006-07-31 10:06) [3]Поищи по файлу #13#10.#13#10
← →
FFx01 © (2006-07-31 22:45) [4]
> А ты бинарный файл посылаеш или текстовый и выражение
> readln(f, bufer);
> Mys(bufer+#13#10); - это зачем если файл бинарный
> размер буфера?
> Может так?
> while not EOF(f) do
> begin
> readln(f, bufer);
> Mys(bufer);
> end;
> Mys(#13#10);
> CloseFile(f);
Посылаю текставой
bufer: array[0..255] of char;
← →
FFx01 © (2006-07-31 22:53) [5]Идет посылка текстового файла, есть подозрение, что размер больше 6кб не нравится серверу.
6 и меньше - письмо доходит.
больше 6 -письмо пересылается, но сервер его не обрабатывает.
Пробовал в base64, результат оказался тот же.
Может, есть у кого готовый примерчик посылки текстового файла?.
← →
ivane (2006-07-31 23:31) [6]А попробуй с ним работать, как с бинарным
← →
Ketmar © (2006-07-31 23:44) [7]а бинарные файлы протокол SMTP понимать и вовсе не обязан. %-)
← →
Dmitry_177 (2006-10-27 23:18) [8]Подскажите пожалуйста, как отправить письмо с аттачем? Обычное письмо я могу отправить...
← →
Ketmar © (2006-10-28 00:48) [9]наверное, дописать к нему аттач? rfc тебе в руки.
← →
Dmitry_177 (2006-10-28 22:18) [10]Читал я... но как послать файл не пойму никак, толи в Base64 надо слать толи еще как, не понятно, если в Base64 то как в него файл перевести и отправить? Правильно ли я задаю параметр boundary? Шлю письмо я так:
function SMTPSendString(AMailSocket: TSocket; Str: String): Boolean;
var
Err: integer;
begin
Str := Str + #13#10;
Err := Send(AMailSocket, Str[1], Length(str), 0);
if Err > 0 then Result := true;
end;
...
SMTPSendString(MailSock, "MIME-Version: 1.0");
SMTPSendString(MailSock, "Content-Type: multipart/mixed; boundary=MyBoundary"); // какой должен быть параметр "boundary"? Правильно ли я его задал?
SMTPSendString(MailSock, "--MyBoundary"); // Надо ли слать эту строку?
SMTPSendString(MailSock, "Content-Type: text/plain; charset=Windows-1251");
SMTPSendString(MailSock, "Test E-Mail " + DateTimeToStr(Now));
SMTPSendString(MailSock, "--MyBoundary"); // Надо ли слать эту строку?
SMTPSendString(MailSock, "Content-Type: application/octet-stream; name="1.txt"");
SMTPSendString(MailSock, "Content-Disposition: attachment; filename="1.txt"");
// Как послать файл???
SMTPSendString(MailSock, "--MyBoundary--"); // Надо ли слать эту строку?
← →
Ketmar © (2006-10-28 22:39) [11]google.com, "content type boundary". по первой же ссылке -- rfc, где всё написано...
посылать надо base64. где гарантия, что в твоём octet-stream не встретится boundary?
← →
Dmitry_177 (2006-10-29 00:47) [12]А все надо в Basr64 отправлять? и txt файлы и exe?
← →
Ketmar © (2006-10-29 00:58) [13]всё.
← →
Dmitry_177 (2006-10-29 01:00) [14]Спасибо.. Вы очень добры...
← →
Dmitry_177 (2006-10-29 17:22) [15]Почитал везде так и не нашел ответа на вопрос... Всеже как мне переводить файл в Base64, считывать побайтно и переводить какнибудь или как?
← →
Anatoly Podgoretsky © (2006-10-29 17:27) [16]> Ответ на сообщение [15]
Различного рода процедур по преобразованию в Base64 по Сети разбросано как
грязи, и обычно Интернет компоненты уже имеют готовые функции.
← →
Dmitry_177 (2006-10-29 17:41) [17]Я видел такую функцию:
function EncodeBase64(Value:string):string;
const Lkp64="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0 123456789+/=";
var c:byte; n:integer; Count:integer; DOut:array[0..3] of Byte;
begin
Result:=EmptyStr;
Count:=1;
while Count<=Length(Value) do
begin
c:=Ord(Value[Count]);
Inc(Count);
DOut[0]:=(c and $FC) shr 2;
DOut[1]:=(c and $03) shl 4;
if Count<=Length(Value) then
begin
c:=Ord(Value[Count]);
Inc(Count);
DOut[1]:=DOut[1]+(c and $F0) shr 4;
DOut[2]:=(c and $0F) shl 2;
if Count<=Length(Value) then
begin
c:=Ord(Value[Count]);
Inc(Count);
DOut[2]:=DOut[2]+(c and $C0) shr 6;
DOut[3]:=(c and $3F);
end
else
begin
DOut[3]:=$40;
end;
end
else
begin
DOut[2]:=$40;
DOut[3]:=$40;
end;
for n:=0 to 3 do
Result:=Result+Lkp64[DOut[n]+1];
end;
end;
и такую:
function EncodeBase64(const inStr: string): string;
function Encode_Byte(b: Byte): char;
const
Base64Code: string[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
begin
Result := Base64Code[(b and $3F)+1];
end;
var
i: Integer;
begin
i := 1;
Result := "";
while i <= Length(InStr) do
begin
Result := Result + Encode_Byte(Byte(inStr[i]) shr 2);
Result := Result + Encode_Byte((Byte(inStr[i]) shl 4) or (Byte(inStr[i+1]) shr 4));
if i+1 <= Length(inStr) then
Result := Result + Encode_Byte((Byte(inStr[i+1]) shl 2) or (Byte(inStr[i+2]) shr 6))
else
Result := Result + "=";
if i+2 <= Length(inStr) then
Result := Result + Encode_Byte(Byte(inStr[i+2]))
else
Result := Result + "=";
Inc(i, 3);
end;
end;
Но они же только строку типа string переводят, а не файл... А как быть с файлом? А еще я заметил, в этих функциях, в константах, с перечислением символов, в некоторых случаях есть в конце символ <>=<> а где нету, всеже он нужен или нет?
← →
Anatoly Podgoretsky © (2006-10-29 18:08) [18]> Ответ на сообщение [17]
Не пробовал догадаться поместить файл в строку?
Или по блочно сфайлом работать, по 54 байта?
А еще лучше написать файловый поток.
← →
Dmitry_177 (2006-10-29 18:14) [19]Как его поместить в строку? Так?
var
FS: TFileStream;
...
FS.Create("c:\1.txt", fmOpenRead);
SMTPSendString(MailSock, String(FS));
FS.Free;
← →
Dmitry_177 (2006-10-29 23:13) [20]Подскажите хотябы так правильно или нет?
← →
Dmitry_177 (2006-10-30 13:45) [21]Почему именно по 54 байта?
Подскажите пожалуйста что не так? Файл присылается, но занимает 0 байт. Помогите...
var
hFile: THandle;
Str: String;
BytesRead: DWord;
...
hFile := CreateFile("c:\1.txt", GENERIC_READ, 0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
ReadFile(hFile, Str[1], 54, BytesRead, nil);
CloseHandle(hFile);
SMTPSendString(MailSock, EncodeBase64(Str));
← →
Dmitry_177 (2006-10-30 13:52) [22]и так пробовал, тоже самое...
ReadFile(hFile, Str[1], GetFileSize(hFile, nil), BytesRead, nil);
← →
atruhin © (2006-10-30 14:29) [23]> Почему именно по 54 байта?
Делай по 108, главное крано 4
← →
Anatoly Podgoretsky © (2006-10-30 15:38) [24]
> Почему именно по 54 байта?
54/3*4=72
А это общепринятое негласное соглашение, результат виден на любом терминале.
Можешь использовать любое другое значение, но не удивляйся, если что то, где то не пройдет. Может у реализатора жестко прописан буфер на 72 символа.
← →
Anatoly Podgoretsky © (2006-10-30 15:39) [25]
> Делай по 108, главное крано 4
Это не обязательно, этим должен заниматься реализатор протокола, но сколько же их кривый и именитых, например The Bat!
← →
Dmitry_177 (2006-10-30 16:25) [26]а если файл меньше 54 байт?
← →
Dmitry_177 (2006-10-30 16:30) [27]Вот функция перевода файла в строку, но она через файловый поток... Но если приложение пишется на одном API, т.е. используются модули только Windows и Messages, не хочется Classes подключать... То нужно через CreateFile и ReadFile реализовывать?
procedure LoadStringFromFile(const FileName: string):string;
var
Stream: TStream;
Size: Integer;
begin
result := "";
Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
try
Size := Stream.Size;
SetString(result, nil, Size);
Stream.Read(Pointer(result)^, Size);
finally
Stream.Free;
end;
end;
← →
Anatoly Podgoretsky © (2006-10-30 16:34) [28]Это ограничение по верхней странице, согласно негласному стандарту, рекомендовано в RFC, строки должны быть не более 72 символов. Но это не догма.
← →
Dmitrij_K (2006-10-30 16:55) [29]
> Dmitry_177
CreateFile - посмотри реализацию функции SysUtils.FileOpen()
Size - Windows.GetFileSize()
ReadFile - SysUtils.FileRead()
закрытие - CloseHandle
← →
Dmitry_177 (2006-10-30 17:11) [30]Что-то вроде получается ))) Строку перевожу в Base64 и для наглядности(в качестве теста) вставляю ее в Memo.. Сделал я так, если файл больше 54 байт, то считываем его по 54 байта в строку, а если нет то в одну строчку...
Как такой алгоритм? Или надо еще как-то? А еще, если файл больше 54 байт я считываю по 54 байт, а последняя строка может быть вовсе и не 54 байта, и при переводе в Base64 оставшееся место стокт может занять мусор, как это убрать это? Я дкмал размер файла поделить на 54 и последнюю строку установить размер длиной на остаток от деления и считать... Но мне кажется это все как-то муторно, наверно есть способ получше, подскажите пожалйста... Заранее спасибо.
var
hFile: THandle;
BytesRead: DWord;
Str: string;
FSize: DWord;
...
hFile := CreateFile("c:\1.txt", GENERIC_READ, 0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
FSize := GetFileSize(hFile, nil);
if FSize > 54 then
begin
SetLength(Str, 54);
repeat
ReadFile(hFile, Str[1], 54, BytesRead, nil);
Memo1.Lines.Add(EncodeBase64(Str));
until BytesRead = 0;
end
else
begin
SetLength(Str, FSize);
ReadFile(hFile, Str[1], FSize, BytesRead, nil);
Memo1.Text := EncodeBase64(Str);
end;
CloseHandle(hFile);
← →
Anatoly Podgoretsky © (2006-10-30 19:18) [31]> Dmitry_177 (30.10.2006 17:11) [30]
Мусор будет, если неправильно реализована функция Base64, как например у The
Bat!
Точнее не мусор, а потеря информации, например заголовок письма будет
обрезаным и при напряженной переписке будет становиться все меньше и меньше.
А с алгоритмом какие проблемы, берез из файла по 54 байта и кодируешь,
последняя строка может быть короче.
← →
Dmitry_177 (2006-10-30 19:33) [32]Я то понимаю ))) Но а как у меня это реализовано?
← →
Anatoly Podgoretsky © (2006-10-30 19:49) [33]> Dmitry_177 (30.10.2006 19:33) [32]
Я не хочу твой код анализировать, вместо него можешь выложить результат для
упаковки 1, 2, 3 и 4 байт. Глазом сразу будет видно правильно сделана
упаковка или нет. Кстати обязательно надо проверить и на 0 байт. Разбиение
на 54/72 символа упаковки не касается, это ограничение транспортных каналов,
никто не мешает упаковать хоть мегабайт одной строкой.
Страницы: 1 вся ветка
Форум: "Сети";
Текущий архив: 2007.04.22;
Скачать: [xml.tar.bz2];
Память: 0.54 MB
Время: 0.058 c