Всем добрый вечер. Работаю с winsock на делфи. Пытаюсь отправить GET запрос на хост, получить ответ и записать его в компонент Memo. Но к сожалению когда доходит очередь до функции recv() - программа просто зависает. В чем моя ошибка? Буду рад любым советам/ответам по теме. Заранее благодарен. P.S. Ответ:"Пиши на АСМ" можете оставить при себе... P.P.S. Может это из-за того, что буфер для отправки имеет тип string с максимальным размером в 255 символов, а GET занимает больше, в следствии чего передается не полный запрос, на который не приходит ответ? И что тогда лучше использовать для буфера, TStringStream? А Pchar покатит?
для буфера не используют string. Лучше pchar а лучше массив из byte. А самый правильный ответ - запусти программу под отладчиком, и посмотри что происходит в этом месте
Так правильней (писал тут, должно работать): Code: unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, winsock, StdCtrls; type TForm1 = class(TForm) Memo1: TMemo; Button1: TButton; Button2: TButton; procedure FormCreate(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; info: WSADATA; sin: sockaddr_in; myip: PHostEnt; sHwnd: integer; sBuff1:string; sBuff, rBuff: array [0..5000] of char; implementation {$R *.dfm} procedure TForm1.FormCreate(Sender: TObject); begin WSAStartup(makeword(1,1),info); sHwnd:=Socket(AF_INET, SOCK_STREAM, 0); sin.sin_family:=AF_INET; sin.sin_port:=htons(80); sin.sin_addr.S_addr:=inet_addr('77.221.159.154'); connect(sHwnd, sin, sizeof(sin)); sbuff1:='GET /article.php?article=1016003 HTTP/1.1' + #13#10 + 'User-Agent: ManualSender/1.0' + #13#10 + 'Host: www.wasm.ru' + #13#10 + #13#10; CopyMemory(@sBuff,pchar(sBuff1),length(sBuff1)); end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin Closesocket(sHwnd); WSACleanup; end; procedure TForm1.Button1Click(Sender: TObject); begin send(sHwnd, sBuff, Length(sBuff), 0); recv(sHwnd, rBuff, Length(rBuff), 0); Memo1.Lines.Add(rBuff); end; end.
ntldr, спасибо за совет. wolmer, спасибо! Твой вариант работает. Данные нормально принимает и ничего не виснет. Woohoo Благодарю еще раз
А еще такой вопрос. Что бы получить данные, нужно знать IP: А каким образом тогда можно реализовать что-то на подобие IdHTTP. Тоесть поле Edit, Button и Memo. Вводишь в Edit ссылку сайта, жмешь на button и результат выводится в Memo. Вся суть в том, как узнать IP, что б подставить в структуру sockaddr_in?
Code: function TForm1.hosttoip(name: string): string; var wsdata :twsadata; hostname:array [0..255] of char; hostent :phostent; addr :pchar; ip :string; begin wsastartup($0101, wsdata); try gethostname (hostname, sizeof (hostname)); strpcopy(hostname, name); hostent := gethostbyname (hostname); if assigned (hostent) then if assigned (hostent^.h_addr_list) then begin addr := hostent^.h_addr_list^; if assigned (addr) then begin ip:=format('%d.%d.%d.%d', [byte (addr [0]), byte(addr [1]), byte (addr [2]), byte (addr [3])]); result := ip; end else result:=''; end else result := '' else begin result := ''; end; finally wsacleanup; end end; (сразу говорю, код не мой, взят с сети) Пример: sin.sin_addr.S_addr:=inet_addr(pchar(hosttoip('yandex.ru'))); {На счет преобр в pchar не уверен. Yandex если что пишется вместе (баг форума)}
Code: memo1.lines.text:=copy(memo1.lines.text, pos(#13#10#13#10, memo1.lines.text)+4, length(memo1.lines.text)-pos(#13#10#13#10, memo1.lines.text));