不用delphi的控件写一个client端的程序!(100分)

  • 主题发起人 主题发起人 liuhulan
  • 开始时间 开始时间
L

liuhulan

Unregistered / Unconfirmed
GUEST, unregistred user!
不用delphi的控件写一个client端的程序!
因为我嫌用了控件后写的程序太大了。
就是完全用winsocket API写,不知道哪里有这样的源程序?
用的协议是TCP/IP。
 
{我写的例子}
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, WinSock,
StdCtrls;

type
TForm1 = class(TForm)
Memo1: TMemo;
Memo2: TMemo;
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
procedure RecvMessage(var Msg: TMessage); message WM_USER + 1;
public
{ Public declarations }
end;

var
Form1: TForm1;
RemoteHost: string;
RemotePort: Integer;
ClientSocket: Integer;
implementation

{$R *.DFM}

{线程处理函数}
function RecvProc(P: Pointer): DWORD;
var
Buffer: PChar;
ret: Integer;
begin
while True do
begin
ret := recv(ClientSocket, Buffer, sizeof(Buffer), 0);
if ret = 0 then
begin
ShowMessage('Socket closed.');
Break;
end
else
if ret = SOCKET_ERROR then
begin
ShowMessage('Read Error.');
Break;
end;
GetMem(Buffer, ret);
SendMessage(HWND(P), WM_USER + 1, 0, Integer(Buffer));
end;
closesocket(ClientSocket);
ClientSocket := INVALID_SOCKET;
Result := WSAGetLastError;
end;

procedure ShowError;
var
ErrorCode: Integer;
begin
ErrorCode := WSAGetLastError;
ShowMessage('Error: ' + IntToStr(ErrorCode));
end;


procedure TForm1.Button1Click(Sender: TObject);
var
sa_in_svr: sockaddr_in;
tid: Cardinal;
begin
sa_in_svr.sin_family := AF_INET;
sa_in_svr.sin_port := htons(RemotePort);
sa_in_svr.sin_addr.S_addr := htonl(inet_addr(PChar(RemoteHost)));

{连接到服务器}
if connect(ClientSocket, sa_in_svr, sizeof(sockaddr_in)) = SOCKET_ERROR then
begin
closesocket(ClientSocket);
ClientSocket := INVALID_SOCKET;
ShowMessage('Failed to connect to server.');
end
else
begin
{创建接收数据线程}
CreateThread(nil, 0, @RecvProc, Pointer(Handle), 0, tid);
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
WSData: WSAData;
ErrorCode: Integer;
sa_in: sockaddr_in;

begin
RemoteHost := '127.0.0.1';
RemotePort := 2000;

{初始化WinSock}
if WSAStartup(MakeWord(1, 1), WSData) <> 0 then
begin
ShowMessage('WinSock initialization fialed.');
Exit;
end;

ClientSocket := socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if ClientSocket = INVALID_SOCKET then
begin
ShowError;
Exit;
end;

sa_in.sin_family := AF_INET;
sa_in.sin_port := htons(0);
sa_in.sin_addr.S_addr := INADDR_ANY;

if bind(ClientSocket, sa_in, sizeof(sockaddr_in)) = SOCKET_ERROR then
begin
closesocket(ClientSocket);
ClientSocket := INVALID_SOCKET;
ShowError;
end;
end;

procedure TForm1.RecvMessage(var Msg: TMessage);
var
P: PChar;
begin
P := PChar(Msg.LParam);
Memo2.Text := String(P);
FreeMem(P);
end;

procedure TForm1.Button2Click(Sender: TObject);
var
buf: PChar;
len: Integer;
begin
buf := PChar(Memo1.Text);
len := Length(Memo1.Text);
send(ClientSocket, buf, len, 0);
end;

end.
 
程序退出时别忘调用WSACleanup
 
呵呵,想写木马? :-)
 
clyin的程序好象有问题,编译是没问题,但是总是出现
运行错误,就是连接不到服务器。10065号错误。
 
这只是一个客户端程序,没有服务器运行,当然连不上了,你把RemoteHost和RemotePort
的值改成有效的主机和端口,就可以了。
 
我使用delphi的clientsocket控见连接远程的时候,如果没有联网,出现windows: socket error:11001
错误,但是我不知道哪里引起了这个错误.如何屏蔽?
 
好象客户端和服务器端都要有固定的IP地址才行。
 
AYellow:当然可以动态更改的。
其实DELPHI自己本身就带有CLIENT/SERVER方面的例子。
 
to jame:
该错误表示主机没有找到。如果没有联网,域名无法解析,就会出错。你可以在Hosts文件
中把该主机名和对应的IP地址加上,就可以屏蔽此错误了。

to liuhulan:
怎么还不结束,好久没分进帐了。:(
 
zengr:
顺便问一句,如果是动态改变的(比如拨号上网)
好像不能用DELPHI自带的CHAT例子,如何办?
呵呵。没分
 
Server端的IP一般是固定的。
Client在连接到Server时,Server就会知道客户端的IP地址
 
接受答案了.
 
后退
顶部