二、编写简单程序
好吧我承认,下面许多内容都翻译自Daniel15的博客。
下文中说的Socket,你可以这样理解:我们读写文件的时候,常需要类似text的类型。所有文件操作均对于这个变量,并且实际作用于那个文件上。这里的Socket类似,实际上代表了这个连接。
在大多数情况下,你会使用TTCPBlockSocket类型。这个类型属于blcksock单元,所以在你的程序中加入下面这个单元声明:
uses blcksock;
下面是一个使用blcksock单元编写网络程序的示例
1.连接到服务器
这也许是你使用Socket时最普遍的方式——直接连接到另一台服务器。这个功能的函数包含在TTCPBlockSocket类型里面。首先,我们需要定义一个变量来存储这个Socket:
var
sock: TTCPBlockSocket;
然后我们自然需要创建这个Socket:
sock := TTCPBlockSocket.Create;
上述语句创造了一个叫sock的Socket类型变量,我们可以使用她了。下一步是连接到远程服务器,使用Connect过程:
sock.Connect('66.79.183.71', '80');
// 是否发生错误?
if sock.LastError <> 0 then
begin
writeLn('Could not connect to server.');
halt(1);
end;
现在,到远程服务器的连接已经被建立,我们可以发送和接受数据了。
2.发送数据
发送数据的过程通过SendString过程实现。注意她和其他一些语言的轻微区别;他不会自动在字符串后加换行符。你需要手工添加换行符,如果这是必要的。
sock.SendString('GET /blog/ HTTP/1.1'
#13#
10'Host:
www.daniel15.com'#13#10#13#10);
3.接受数据
blcksock 单元提供了很多接受数据的过程,但是主要的两个是RecvString和RecvPacket。RecvString从Socket读入单个的字符串,以换行符结束,并且返回一个没有换行符的字符串。RecvPacket则会读入所有等待被读的数据,并且毫无修改地返回这个字符串(所有换行符都仍会在那儿)。两个命令都需要一个参数:超时时间(timeout)。如果这个Socket在timeout内没有任何数据,则会返回一个空白的字符串。
buffer := sock.RecvPacket(2000);
现在我们把上面的语句串联起来。
这是一个简单的程序,连接一个web服务器,进行一次简单的询问,并将返回内容打印在屏幕上。
program TestApp;
uses
blcksock;
var
sock: TTCPBlockSocket;
procedure Main();
var
buffer: String = '';
begin
sock := TTCPBlockSocket.Create;
sock.Connect('66.79.183.71', '80');
// 是否发生错误?
if sock.LastError <> 0 then
begin
writeLn('Could not connect to server.');
halt(1);
end;
// 发送一个HTTP请求
sock.SendString('GET /blog/ HTTP/1.1'
#13#
10'Host:
www.daniel15.com'#13#10#13#10);
// 保持循环
repeat
buffer := sock.RecvPacket(2000);
write(buffer);
// 直到没有更多的数据
until buffer = '';
end;
begin
Main();
end.
循环是需要的,因为数据可能通过多个包传输。
这个并不是一个很好的示例,因为在synapse中,已经内建了HTTP单元(名为httpsend)。内建的HTTP单元有很多好处,包括使用HTTP代理,以及更简单的调用。然而blcksock是最基本的单元。也许我会在以后的文章中涉及。