C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
Помогите отладить код, Помогите отладить код
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 опередил. biggrin.gif

Отредактировано 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

Прикрепляю не самый удачный посылатель мыла, но он работает. Можете сравнивать свой код с ним. smile.gif

User Attached Image Скачать файл
AxSendSMS.cpp


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



А инициализировать сокеты? smile.gif У вас же в примере это было.

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'ов

Просто это я делаю при старте и перед выходом из приложения. smile.gif

Отредактировано 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



А как можно принимать почту?

Вернуться в Вопросы программирования в C++Builder