Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 2004.02.29;
Скачать: [xml.tar.bz2];

Вниз

Проблема с сокетами   Найти похожие ветки 

 
denkop   (2003-12-16 01:47) [0]

Делаю так:

function LookupName(const Name: string): TInAddr; {это я выдрал из VCL}
var
HostEnt: PHostEnt;
InAddr: TInAddr;
begin
HostEnt := gethostbyname(PChar(Name));
ShowMessage("1=");
FillChar(InAddr, SizeOf(InAddr), 0);
if HostEnt <> nil then
begin
with InAddr, HostEnt^ do
begin
S_un_b.s_b1 := h_addr^[0];
S_un_b.s_b2 := h_addr^[1];
S_un_b.s_b3 := h_addr^[2];
S_un_b.s_b4 := h_addr^[3];
end;
end;
Result := InAddr;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
nSMTPServerSocket := socket(PF_INET, SOCK_STREAM, 0);
ShowMessage(IntToStr(nSMTPServerSocket));{здесь нормально}
smtp_address.sin_family := AF_INET;
smtp_address.sin_addr:=LookupName("smtp.aaanet.ru");
smtp_address.sin_port := 25;
nConnect := connect(nSMTPServerSocket, smtp_address,sizeof(smtp_address));
ShowMessage(IntToStr(nConnect));{здесь -1}

for i:=1 to 7 do
begin
recv(nSMTPServerSocket, sBuf, sizeof(string), 0);
Memo1.Lines.Add(sBuf);
send(nSMTPServerSocket,MailMessage[iMsg], Length(MailMessage[iMsg]),0);
end;
ShowMessage("Complete");
end;

Мне кажется баг таится где-то в формировании sin_addr. Других вариантов не нашёл как по хосту получить ip.


 
Digitman   (2003-12-16 08:22) [1]

плохо ты "выдрал")

где вызов WSAStartup() ??

ты сам мог бы понять свою ошибку, если бы взял за хорошую привычку анализировать причину отказа winsock-функций вызовом WSAGetLastError()


 
denkop   (2003-12-16 19:04) [2]

Прошу не ругаться на меня, т.к. напрямую с winsock.pas ничего ранее не использовал.
Я исправился, вот код:
var
D:WSAData;
S:TSocket;
A:TSockAddr;
IPName:string;

begin
if HostToIP("smtp.aaanet.ru",IPName) then
WriteLn("IP=",IPName) else WriteLn("Error define IP");
{IP опред нормально}
if WSAStartup($101,D)<>0 then
begin
writeln("error WSAStartUp");
exit;
end;
A.sin_family:=AF_INET;
A.sin_addr.S_addr:=inet_addr(pchar(IPName));
A.sin_port := 25;
S:=socket(AF_INET,SOCK_STREAM,0);
if S=INVALID_SOCKET then writeln("error socket init")
else WriteLn("socket handle=",S);{Здесь тоже всё в норме}
if connect(S,A,sizeof(A))<>0 then
WriteLn("Cannot connect to socket, error: ",
WSAGetLastError); {А вот здесь всё плохо}
WSACleanup;
WriteLn("Complete");
ReadLn;
end.

После коннекта получаю ошибку 10061-WSAECONNREFUSED. Через telnet всё работает, т.е. сервер функционирует нормально.


 
Digitman   (2003-12-17 08:23) [3]

после успешного вызова socket(), но ПЕРЕД вызовом connect() ты обязан вызвать bind(), чтобы занять любой свободный порт


 
Digitman   (2003-12-17 08:28) [4]

это тебе в помощь

http://book.itep.ru/7/sock_71.htm

там ты найдешь графически представленную циклограмму, наглядно поясняющую механизм установления вирт.петли соединения при использовании TCP-протокола, а так же соотв.послед-ть Winsock-вызовов


 
Verg   (2003-12-17 09:50) [5]


> A.sin_port := htons( 25 );


 
Verg   (2003-12-17 10:03) [6]


> Digitman © (17.12.03 08:23) [3]
> после успешного вызова socket(), но ПЕРЕД вызовом connect()
> ты обязан вызвать bind(), чтобы занять любой свободный порт


Клиенту нет необходимости вызывать bind до вызова connect: при необходимости ядро выберет и динамически назначаемый порт, и IP-адрес отправителя.
Ядро выбирает IP-адрес отправителя в момент подключения клиента к сокету, основываясь на используемом исходящем интерфейсе, который, в свою очередь, зависит от маршрута, требуемого для обращения к серверу.


 
Digitman   (2003-12-17 10:13) [7]


> Verg


ты прав.
явный bind() нужен лишь серверной стороне


 
denkop   (2003-12-17 20:36) [8]


> Digitman

Дельная дока!
У меня не хватало htons( 25 );
Соединение получилось, но вот с приёмом передачей туго.
Вот получившийся код:

program Project1;

{$APPTYPE CONSOLE}

uses
SysUtils,
WinSock,
GFiles;

{$R *.res}

var
D:WSAData;
S:TSocket;
A:TSockAddr;
Buf,Cmd,IPName:string;
f:textfile;

begin
Assign(f,"debug.log");
try
Rewrite(f);
if HostToIP("smtp.aaanet.ru",IPName) then
WriteLn(f,"IP=",IPName) else WriteLn(f,"Error define IP");
if WSAStartup($101,D)<>0 then
begin
writeln(f,"error WSAStartUp");
exit;
end;
A.sin_family:=AF_INET;
A.sin_addr.S_addr:=inet_addr(pchar(IPName));
A.sin_port :=htons(25);
S:=socket(AF_INET,SOCK_STREAM,IPPROTO_IP);
if S=INVALID_SOCKET then writeln(f,"error socket init")
else WriteLn(f,"socket handle=",S);
if connect(S,A,sizeof(A))<>0 then
WriteLn(f,"Cannot connect to socket, error: ",WSAGetLastError)
else WriteLn(f,"Connected");
Cmd:="HELO smtp.aaanet.ru"+#10#13;
Send(S,Cmd,SizeOf(Cmd),0);
WriteLn(Cmd);
Recv(S,buf,255,0);
WriteLn(f,buf);
WriteLn(f,"Complete");
finally
WSACleanup;
Close(f);
end;
ReadLn;
end.

После Recv программа молча вылетает безо всяких предупреждений.


 
Digitman   (2003-12-18 08:27) [9]


> У меня не хватало htons( 25 );


надеюсь, тебе понятно, что делает эта ф-ция и почему


> После Recv программа молча вылетает безо всяких предупреждений


она (программа) и передает у тебя далеко не то что ты ожидаешь

//передача
BytesSent := Send(S,Cmd[0],Length(Cmd),0);

//прием
SetLength(buf, 255);
BytesReceived := Recv(S,buf[0], Length(buf),0);

p.s.
рановато ты взялся за API, потому как знания ObjectPascal у тебя оставляют желать лучшего


 
denkop   (2003-12-21 11:41) [10]

SetLength(buf, 255); - прощёлкал.
А почему Cmd[0] а не просто Cmd?


 
Digitman   (2003-12-21 13:54) [11]

и даже не Cmd[0], а Cmd[1] - это уже я ошибся

потому что Cmd[1] вернет ссылку на 1-й символ подготовленного строкового буфера (т.е. начало собственно буфера) , в то время как Cmd вернет ссылку не на начало буфера, а не адрес управляющей структуры, относящейся к переменной String (String = AnsiString - тип динамический, а не статический) ...

адрес начала дин.структуры и адрес начала буфера, на который ссылается некое поле этой дин.структуры - не одно и тоже


 
denkop   (2003-12-23 22:49) [12]

Мда, верно... Спасибо за помощь.



Страницы: 1 вся ветка

Форум: "Сети";
Текущий архив: 2004.02.29;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.47 MB
Время: 0.038 c
14-94167
mfender
2004-02-07 18:49
2004.02.29
Индульгенция


1-93921
p_sA[11]
2004-02-15 12:01
2004.02.29
Что за трабла с MEMO???


14-94128
Ega23
2004-02-09 10:34
2004.02.29
Programming Windows Driver Model


14-94129
Домарощинер
2004-02-09 19:57
2004.02.29
Классный плагиат


14-94175
Sergo
2004-02-07 10:19
2004.02.29
RW (Nero)





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский