Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 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
15-1174050490
Rule
2007-03-16 16:08
2007.04.22
УРАААААААААА, я купил машину :-)))


2-1175281898
Sholah_Weras
2007-03-30 23:11
2007.04.22
Высота/Ширина рисунка.


2-1175620219
malyar
2007-04-03 21:10
2007.04.22
указатель на массив


1-1172427326
Dmitry_177
2007-02-25 21:15
2007.04.22
Убрать тень от своего курсора в программе


3-1170212620
Flagman
2007-01-31 06:03
2007.04.22
Вычленить время из TIMESTAMP (Oracle)





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский