serg128 |
Отправлено: 20.09.2005, 15:47 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 46
|
Народ, помогите отладить код:
создал класс для отправки почты
#include
#include
class TMail
{
public:
AnsiString Smtp; // IP-addr smtp
unsigned int Port; // smtp port
AnsiString From;
AnsiString Dest;
AnsiString Subj;
AnsiString Body;
bool mail()
{
try
{
WSAStartup(257, WSAData);
Sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
if(Sock == INVALID_SOCKET) return 0;
Res = inet_addr(Smtp.c_str());
if(!Res) return 0;
Host->sin_family = AF_INET;
Host->sin_port = Port;
Host->sin_addr.S_un.S_addr = Res;
if(connect(Sock, (const sockaddr*)Host, sizeof(Host)))
return 0;
if(!recvdata("220"))
return 0;
senddata("EHLO\r\n");
if(!recvdata("250"))
return 0;
senddata("MAIL FROM: " + From + "\r\n");
if(!recvdata("250"))
return 0;
senddata("RCPT TO:" + Dest + "\r\n");
if(!recvdata("250"))
return 0;
senddata("DATA\r\n");
if(!recvdata("354"))
return 0;
senddata("Subject:" + Subj + "\r\n\r\n" + Body + "\r\n.");
if(!recvdata("250"))
return 0;
senddata("QUIT\r\n");
}
__finally
{
closesocket(Sock);
WSACleanup();
return 1;
}
}
__fastcall TMail(){};
private:
TWSAData *WSAData;
TSockAddrIn *Host;
TSocket Sock;
int Res;
char Buff[255];
void __fastcall senddata(AnsiString str)
{
for(int i=0; i
{
if(send(Sock, (const char*)str.c_str()[i], 1, 0) == SOCKET_ERROR)
return;
}
}
bool __fastcall recvdata(AnsiString accept)
{
char Buff[255];
Res = recv(Sock, Buff, sizeof(Buff), 0);
return (Res == SOCKET_ERROR) || (AnsiString(Buff).SubString(1, 3) == accept);
}
};
Использую так:
TMail *m = new TMail();
m->Port = 25;
m->From = "host@kiev.velton.ua";
m->Dest = "host@kiev.velton.ua";
m->Smtp = "85.90.192.130";
m->Body = "Test message";
m->mail();
А на строке:
Host->sin_family = AF_INET;
Вылазит exception.
Помгите найти проблему. Использую С++ Билдер6.
Заранее спасибо!
|
|
Guest |
Отправлено: 20.09.2005, 16:39 |
|
Не зарегистрирован
|
???
bind
htons(25)
Что есть Host
EHLO
???
sockaddr_in sadr_trg;
sadr_trg.sin_family = AF_INET;
sadr_trg.sin_port = htons(25);
sadr_trg.sin_addr.s_addr = inet_addr(smsSMTP.c_str());
Лучше асинхронный сокет. |
|
serg128 |
Отправлено: 20.09.2005, 21:07 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 46
|
И что, так работает? |
|
serg128 |
Отправлено: 21.09.2005, 08:55 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 46
|
определён в секции private:
TSockAddrIn *Host;
|
|
AVC |
Отправлено: 21.09.2005, 09:12 |
|
Ветеран
Группа: Модератор
Сообщений: 1583
|
QUOTE |
А на строке:
Host->sin_family = AF_INET;
Вылазит exception
|
Закономерно.
Вы используете "мусорный" указатель.
TSockAddrIn *Host; // на что это указывает ???
// sizeof(Host) = 4
// sizeof(*Host) = 16;
Можно так
TSockAddrIn Host;
Host.sin_port = htons(25);
Привыкайте использовать htons tcp/ip использует порядок байтов не такой как в памяти.
Отредактировано AVC — 21/09/2005, 08:56 |
|
Asher |
Отправлено: 21.09.2005, 09:17 |
|
Мастер участка
Группа: Модератор
Сообщений: 550
|
У вас Host не существует.
Только указатель на него.
Вообще то, там сделано так:
typedef sockaddr_in TSockAddrIn;
Так что уберите * в описании TSockAddrIn *Host;
и в качестве селектора используйте . а не->
Так, как вам это serg128 написал
P.S. пока писал отвлекали и AVC опередил.
Отредактировано Asher — 21/09/2005, 10:18
|
|
serg128 |
Отправлено: 21.09.2005, 10:51 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 46
|
Благдарствую, кусок переписал так:
Res = inet_addr(Smtp.c_str());
if(!Res) return 0;
Host.sin_family = AF_INET;
Host.sin_port = htons(Port);
Host.sin_addr.s_addr = Res;
Но коннектиться он упорно нехочет:
if(connect(Sock, (struct sockaddr*)&Host, sizeof(Host)))
return 0;
Почему такое происходит? |
|
AVC |
Отправлено: 21.09.2005, 11:18 |
|
Ветеран
Группа: Модератор
Сообщений: 1583
|
QUOTE (Guest @ 20/09/2005, 15:39) | ???
bind
htons(25)
Что есть Host
EHLO
???
|
bind
Прикрепляю не самый удачный посылатель мыла, но он работает. Можете сравнивать свой код с ним.
|
|
serg128 |
Отправлено: 21.09.2005, 12:52 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 46
|
tSocket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (tSocket == INVALID_SOCKET) return false;
Почему-то вылетает на этой проверке. Файрвола у меня нет, в чём проблема, если скрипт работал? |
|
AVC |
Отправлено: 21.09.2005, 13:13 |
|
Ветеран
Группа: Модератор
Сообщений: 1583
|
А инициализировать сокеты? У вас же в примере это было.
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = 0x0101; // MAKEWORD(2,0);
// инициализируем Socket'ы
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0) // Tell the user that we couldn't find a usable WinSock DLL.
throw Exception ("WSAStartup Error Code: " + WSAErrorAsText());
if (wsaData.wVersion != wVersionRequested)
throw Exception ("WinSock version 1.1 not supported");
ну и в конеце
WSACleanup(); // деинициализаци socket'ов
Просто это я делаю при старте и перед выходом из приложения.
Отредактировано AVC — 21/09/2005, 12:15 |
|
serg128 |
Отправлено: 21.09.2005, 13:31 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 46
|
Супер!!!
Заработало. Спасибо огромное!
А если почтовик находится за прокси-сервером? Возможно ли вообще отправить так почту.
И можно-ли приаттачить как-то файл к письму? |
|
avc* |
Отправлено: 21.09.2005, 13:49 |
|
Не зарегистрирован
|
Это простенькая функция. Для более сложного почтового клиента я вам давал ссылку на посты Devnvd
|
|
serg128 |
Отправлено: 21.09.2005, 15:46 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 46
|
А как можно принимать почту?
|
|