![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Не посылается письмо размером больше 6 кб
FFx01 © (2006-07-27 06:47:00)Пытаюсь выслать сообщение(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.
Anatoly Podgoretsky (2006-10-30 19:49:00) [1]> Dmitry_177 (30.10.2006 19:33) [32]
Я не хочу твой код анализировать, вместо него можешь выложить результат для
упаковки 1, 2, 3 и 4 байт. Глазом сразу будет видно правильно сделана
упаковка или нет. Кстати обязательно надо проверить и на 0 байт. Разбиение
на 54/72 символа упаковки не касается, это ограничение транспортных каналов,
никто не мешает упаковать хоть мегабайт одной строкой.
Dmitry_177 (2006-10-30 19:33:00) [2]Я то понимаю ))) Но а как у меня это реализовано?
Anatoly Podgoretsky (2006-10-30 19:18:00) [3]> Dmitry_177 (30.10.2006 17:11) [30]
Мусор будет, если неправильно реализована функция Base64, как например у The
Bat!
Точнее не мусор, а потеря информации, например заголовок письма будет
обрезаным и при напряженной переписке будет становиться все меньше и меньше.
А с алгоритмом какие проблемы, берез из файла по 54 байта и кодируешь,
последняя строка может быть короче.
Dmitry_177 (2006-10-30 17:11:00) [4]Что-то вроде получается ))) Строку перевожу в 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);
Dmitrij_K (2006-10-30 16:55:00) [5]
> Dmitry_177
CreateFile - посмотри реализацию функции SysUtils.FileOpen()
Size - Windows.GetFileSize()
ReadFile - SysUtils.FileRead()
закрытие - CloseHandle
Anatoly Podgoretsky (2006-10-30 16:34:00) [6]Это ограничение по верхней странице, согласно негласному стандарту, рекомендовано в RFC, строки должны быть не более 72 символов. Но это не догма.
Dmitry_177 (2006-10-30 16:30:00) [7]Вот функция перевода файла в строку, но она через файловый поток... Но если приложение пишется на одном 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;
Dmitry_177 (2006-10-30 16:25:00) [8]а если файл меньше 54 байт?
Anatoly Podgoretsky (2006-10-30 15:39:00) [9]
> Делай по 108, главное крано 4
Это не обязательно, этим должен заниматься реализатор протокола, но сколько же их кривый и именитых, например The Bat!
Anatoly Podgoretsky (2006-10-30 15:38:00) [10]
> Почему именно по 54 байта?
54/3*4=72
А это общепринятое негласное соглашение, результат виден на любом терминале.
Можешь использовать любое другое значение, но не удивляйся, если что то, где то не пройдет. Может у реализатора жестко прописан буфер на 72 символа.
atruhin (2006-10-30 14:29:00) [11]> Почему именно по 54 байта?
Делай по 108, главное крано 4
Dmitry_177 (2006-10-30 13:52:00) [12]и так пробовал, тоже самое...
ReadFile(hFile, Str[1], GetFileSize(hFile, nil), BytesRead, nil);
Dmitry_177 (2006-10-30 13:45:00) [13]Почему именно по 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-29 23:13:00) [14]Подскажите хотябы так правильно или нет?
Dmitry_177 (2006-10-29 18:14:00) [15]Как его поместить в строку? Так?
var
FS: TFileStream;
...
FS.Create('c:\1.txt', fmOpenRead);
SMTPSendString(MailSock, String(FS));
FS.Free;
Anatoly Podgoretsky (2006-10-29 18:08:00) [16]> Ответ на сообщение [17]
Не пробовал догадаться поместить файл в строку?
Или по блочно сфайлом работать, по 54 байта?
А еще лучше написать файловый поток.
Dmitry_177 (2006-10-29 17:41:00) [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 17:27:00) [18]> Ответ на сообщение [15]
Различного рода процедур по преобразованию в Base64 по Сети разбросано как
грязи, и обычно Интернет компоненты уже имеют готовые функции.
Dmitry_177 (2006-10-29 17:22:00) [19]Почитал везде так и не нашел ответа на вопрос... Всеже как мне переводить файл в Base64, считывать побайтно и переводить какнибудь или как?
Dmitry_177 (2006-10-29 01:00:00) [20]Спасибо.. Вы очень добры...