TCP通讯
由于delphi的SOCKET组件在默认的情况下是没有被添加大组件库中的,如果你没有使用过SOCKET组件,在打开时就会提示TClientSocket或TServerSocket等控件没有被声明而不能编译通过;
解决办法:
添加组件草开发环境里面component->install package->add->"C:\Program Files\Borland\Delphi7\Bin\dclsockets70.bpl" 添加后在组件Internet页面可以看到TSocketClient和TSocketServer控件
客户端TSocketClient需要映射连接OnConnect、断开OnDisconnect及读取OnRead消息三个事件,服务器端TSocketServer也需要对应的映射监控是否有客户端连接上的OnClientConnect事件,客户端断开OnClientDisconnect事件及读取客户端数据的OnClientRead
服务器端TSocketServer只需提供客户端的连接端口ServerSocket.Port,然后打开ServerSocket.Open();就可以供客户端连接了;然后那三个事件就分别来处理连接时,断开时,及读取消息时的事件;
procedure TForm1.OnClientConnect(Sender: TObject; Socket: TCustomWinSocket);
这里Socket就是连接上的套接字,通过它可以获取远程客户端IP及端口,分别是Socket.RemoteAddress和Socket.Port;
procedure TForm1.OnClientDisconnect(Sender: TObject;
Socket: TCustomWinSocket); 通过socket判断哪些客户端已经断开了
procedure TForm1.OnClientRead(Sender: TObject; Socket: TCustomWinSocket); 用该事件来接收客户端发来的数据,Socket.ReceiveText,是以字符串形式接收的,当然发送也是以字符串形式发送的CustomWinSocket[Socket].SendText(string);这里的CustomWinSocket就是定义的TCustomWinSocket类,当然在实际应用过程中接收和发送数据都要有一定的规范,所以要掌握一些字符串和数组,字节之间的转换。
客户端TSocketClient需提供指定远程服务器地址和端口才能连接远程服务器,远程服务器地址一般是服务器IP,ClientSocket1.Address和ClientSocket1.Port,然后打开clientSocket1.Open();只要服务器将端口打开了就可以连接了;然后那三个事件就和服务器的三个事件一样,分别来处理连接时,断开时,及读取消息时的事件;不过客户端读取和服务器读取数据有一点点不同,就是它接收数据是以无类型的Buf来接收的,Socket.Receivebuf(RecBuf,200);这里的RecBuf:array[0..255] of char;是个字符数组,最后显示时需用StrPas函数转换了显示;当然这里接收也可以用其他形式存储,根据实际需要选择。
下面的程序非常的简单,只是一个在服务器和客户机之间建立连接并通讯的程序。
我们使用TServerSocket组件来建立服务器端的程序。
它包含两个memo组件,用来分别处理接收到的数据和发送的数据,然后再在窗体上方一个TServerSocket组件,ServerType设置为stNonBlocking,Port设置为100,active设置为true,写几句简单的代码如下:
{
作者:wudi_1982
联系方式:wudi_1982@hotmail.com
转载请著名出处
}
unit Unit1;
![DELPHI7 TCP、UDP通讯(winsock)(转) - liang_liu99 - 哈是浮云的计算机技术博客](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
interface
![DELPHI7 TCP、UDP通讯(winsock)(转) - liang_liu99 - 哈是浮云的计算机技术博客](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, StdCtrls, ScktComp;
![DELPHI7 TCP、UDP通讯(winsock)(转) - liang_liu99 - 哈是浮云的计算机技术博客](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
type
TForm1
=
class
(TForm)
ServerSocket1: TServerSocket;
Memo1: TMemo;
Button1: TButton;
StatusBar1: TStatusBar;
Memo2: TMemo;
procedure ServerSocket1ClientConnect(Sender: TObject;
Socket: TCustomWinSocket);
procedure ServerSocket1ClientDisconnect(Sender: TObject;
Socket: TCustomWinSocket);
procedure ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
![DELPHI7 TCP、UDP通讯(winsock)(转) - liang_liu99 - 哈是浮云的计算机技术博客](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
var
Form1: TForm1;
![DELPHI7 TCP、UDP通讯(winsock)(转) - liang_liu99 - 哈是浮云的计算机技术博客](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
implementation
![DELPHI7 TCP、UDP通讯(winsock)(转) - liang_liu99 - 哈是浮云的计算机技术博客](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
{$R *.dfm}
![DELPHI7 TCP、UDP通讯(winsock)(转) - liang_liu99 - 哈是浮云的计算机技术博客](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
procedure TForm1.ServerSocket1ClientConnect(Sender: TObject;
Socket: TCustomWinSocket);
begin
StatusBar1.SimpleText :
=
'
connect
'
;
end;
![DELPHI7 TCP、UDP通讯(winsock)(转) - liang_liu99 - 哈是浮云的计算机技术博客](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
procedure TForm1.ServerSocket1ClientDisconnect(Sender: TObject;
Socket: TCustomWinSocket);
begin
StatusBar1.SimpleText :
=
'
disconnect
'
;
end;
![DELPHI7 TCP、UDP通讯(winsock)(转) - liang_liu99 - 哈是浮云的计算机技术博客](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
begin
Memo1.Lines.Add( Socket.ReceiveText);
end;
![DELPHI7 TCP、UDP通讯(winsock)(转) - liang_liu99 - 哈是浮云的计算机技术博客](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
procedure TForm1.Button1Click(Sender: TObject);
begin
if
ServerSocket1.Active then
ServerSocket1.Socket.Connections[
0
].SendText(Memo2.Text);
end;
![DELPHI7 TCP、UDP通讯(winsock)(转) - liang_liu99 - 哈是浮云的计算机技术博客](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
end.
然后编译程序。
客户端实现:
客户端相对复杂一些,因为我们要有一个用来接收服务器IP地址的edit,以及端口地址的edit。
{
作者:wudi_1982
联系方式:wudi_1982@hotmail.com
转载请著名出处
}
unit Unit1;
![DELPHI7 TCP、UDP通讯(winsock)(转) - liang_liu99 - 哈是浮云的计算机技术博客](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
interface
![DELPHI7 TCP、UDP通讯(winsock)(转) - liang_liu99 - 哈是浮云的计算机技术博客](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, StdCtrls, ScktComp;
![DELPHI7 TCP、UDP通讯(winsock)(转) - liang_liu99 - 哈是浮云的计算机技术博客](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
type
TForm1
=
class
(TForm)
ClientSocket1: TClientSocket;
edIp: TEdit;
Label1: TLabel;
Label2: TLabel;
edPort: TEdit;
StatusBar1: TStatusBar;
Memo1: TMemo;
btnConnect: TButton;
btnSent: TButton;
btnDisconnect: TButton;
Memo2: TMemo;
procedure ClientSocket1Connect(Sender: TObject;
Socket: TCustomWinSocket);
procedure btnConnectClick(Sender: TObject);
procedure btnDisconnectClick(Sender: TObject);
procedure btnSentClick(Sender: TObject);
procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
private
{ Private declarations }
public
{ Public declarations }
end;
![DELPHI7 TCP、UDP通讯(winsock)(转) - liang_liu99 - 哈是浮云的计算机技术博客](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
var
Form1: TForm1;
![DELPHI7 TCP、UDP通讯(winsock)(转) - liang_liu99 - 哈是浮云的计算机技术博客](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
implementation
![DELPHI7 TCP、UDP通讯(winsock)(转) - liang_liu99 - 哈是浮云的计算机技术博客](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
{$R *.dfm}
![DELPHI7 TCP、UDP通讯(winsock)(转) - liang_liu99 - 哈是浮云的计算机技术博客](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
procedure TForm1.ClientSocket1Connect(Sender: TObject;
Socket: TCustomWinSocket);
begin
StatusBar1.SimpleText :
=
'
连接成功
'
;
end;
![DELPHI7 TCP、UDP通讯(winsock)(转) - liang_liu99 - 哈是浮云的计算机技术博客](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
procedure TForm1.btnConnectClick(Sender: TObject);
begin
if
not ClientSocket1.Active then
begin
ClientSocket1.Host :
=
edIp.Text;
ClientSocket1.Port :
=
StrToInt(edPort.Text);
ClientSocket1.Open;
(Sender
as
TButton).Enabled :
=
false
;
btnDisconnect.Enabled :
=
true
;
end;
end;
![DELPHI7 TCP、UDP通讯(winsock)(转) - liang_liu99 - 哈是浮云的计算机技术博客](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
procedure TForm1.btnDisconnectClick(Sender: TObject);
begin
if
ClientSocket1.Active then
begin
ClientSocket1.Close;
btnDisconnect.Enabled :
=
false
;
btnConnect.Enabled :
=
true
;
![DELPHI7 TCP、UDP通讯(winsock)(转) - liang_liu99 - 哈是浮云的计算机技术博客](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
end;
end;
![DELPHI7 TCP、UDP通讯(winsock)(转) - liang_liu99 - 哈是浮云的计算机技术博客](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
procedure TForm1.btnSentClick(Sender: TObject);
begin
if
ClientSocket1.Active then
ClientSocket1.Socket.SendText(Memo1.Text)
end;
![DELPHI7 TCP、UDP通讯(winsock)(转) - liang_liu99 - 哈是浮云的计算机技术博客](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
procedure TForm1.ClientSocket1Read(Sender: TObject;
Socket: TCustomWinSocket);
begin
Memo2.Lines.Add(Socket.ReceiveText);
end;
![DELPHI7 TCP、UDP通讯(winsock)(转) - liang_liu99 - 哈是浮云的计算机技术博客](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
end