本文整理自网络,侵删。
Delphi 10.3 社区版
测试用 TIdTCPClient 去连接一个 HTTP 服务器,自己写 HTTP 请求,发现一个问题。
大致步骤如下:
1. 首先,用 TCP 客户端,连接一个 HTTP 服务器;
2. 向服务器发送 HTTP 请求字符串;
3. 从服务器读返回值;
向服务器发送字符串的方法是:
IdTCPClient1.IOHandler.Write(IB1); //这里的 IB1 是 TIdBytes;
读返回值的方法是:
IdTCPClient1.IOHandler.ReadBytes(IB2, -1); // IB2 是 TIdBytes; 这里的 -1 是要读的字节数。
如果把要读的字节数,设置为一个正数,比如 100,同时设置超时:IdTCPClient1.IOHandler.ReadTimeout := 50;
假设服务器返回的字节数只有 80 则读会超时,但是,超时后,收到的 IB2 是空的!原本以为它会返回 80个字节的内容呢。
因此,如果你不知道要读多少字节,这里必须用 -1,然后超时后,获得的 IB2 的字节数就是服务器返回的字节数。
TIdTCPClient 的这个特性,不知道是不是一个 BUG,但显然不符合编程的直觉。
看 TIdIOHandler.ReadBytes 这个函数的源代码,似乎是读够了数据就退出,退出读以后才把读到的字节拷贝到这个函数的输出变量里面。没读够超时,可能超时引发的异常导致了没拷贝进去。
另外,HTTP 协议:
用 TCP 连上服务器以后,需要发一个 HTTP 头给服务器,才能获得服务器的响应。(服务器是 Indy Web Server)。
HTTP 头实际上是几行字符串,字符串之间用回车换行分隔。最后还要加上一个回车换行(空行)作为结束。
构成 HTTP 头的代码如下,这里的 SL 是 TStringList:
SL := TStringList.Create; try SL.Add('GET / HTTP/1.1'); SL.Add('Host: 127.0.0.1:8080'); SL.Add('Connection: keep-alive'); SL.Add('Upgrade-Insecure-Requests: 1'); SL.Add('User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'); SL.Add('Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8'); SL.Add('Accept-Encoding: gzip, deflate'); SL.Add('Accept-Language: zh-CN,zh;q=0.9'); SL.Add(''); S1 := SL.Text; finally SL.Free; end;上述 http 头,如果只有第一行,拿不到服务器的返回。
测试 www.qq.com 的服务器,上述 HTTP 头,如果只有第一行,也能获得服务器的返回字符串,只不过这个字符串是: 404 not found 等等提示。――――――――――――――――
原文链接:https://blog.csdn.net/pcplayer/article/details/89345192
相关阅读 >>
decodedate:从一个tdatetime变量中提取年、月、日数值
Delphi createprocesswithlogonw用法
Delphi keydown与keyup、keypress的区别
更多相关阅读请进入《Delphi》频道 >>