Y
yourkeychen
Unregistered / Unconfirmed
GUEST, unregistred user!
------------------------------以下是服务端的程序-----------------------------
unit test_server;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Sockets, SUIButton, StdCtrls, SUIEdit, DBXpress, DB, SqlExpr,
IdBaseComponent, IdComponent, IdTCPServer, ScktComp, ComCtrls, ExtCtrls,
Grids, DBGrids, WinSkinData, WinSkinForm, Buttons;
type
TForm1 = class(TForm)
Panel1: TPanel;
StatusBar1: TStatusBar;
ServerSocket1: TServerSocket;
Memo1: TMemo;
DBGrid1: TDBGrid;
TreeView1: TTreeView;
WinSkinForm1: TWinSkinForm;
SkinData1: TSkinData;
ListBox1: TListBox;
EdtVodPath: TEdit;
BitBtn1: TBitBtn;
BitBtn2: TBitBtn;
BitBtn3: TBitBtn;
ProgressBar1: TProgressBar;
procedure FormCreate(Sender: TObject);
procedure ServerSocket1ClientConnect(Sender: TObject;
Socket: TCustomWinSocket);
procedure ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
procedure ServerSocket1Accept(Sender: TObject;
Socket: TCustomWinSocket);
procedure ServerSocket1ClientError(Sender: TObject;
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
procedure ServerSocket1ClientDisconnect(Sender: TObject;
Socket: TCustomWinSocket);
procedure BitBtn1Click(Sender: TObject);
procedure BitBtn2Click(Sender: TObject);
procedure BitBtn3Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
const
UniqueAppstr='I_AM_UNIQUE_APP';
PASSID = '!$@%*#^('; //用户名和密码传送前导标志
FSIZEID = '~!@#$%'; //文件长度前导标志
MAX_LEN = 2048;
ENDID = '@@@12@13@14@@41@31@21@@@'; //24位传输结束标志
bufsize = 1460; //缓冲区大小
var
Form1: TForm1;
function checkpass(userinfo,passinfo:string):boolean;
//验证口令字
procedure DirToTreeView(ATreeView: TTreeView; ADirectory: string;
ARoot: TTreeNode; AIncludeFiles: Boolean);
//把指定的目录返回到 TreeView 结构中
procedure SendVodDir;
//发送影片目录文件到客户端
implementation
uses U_DataModule1, U_adduser;
var
total_user : integer=0; //在线用户合计数
DefaultHost : string = '192.168.0.2'; //默认主机地址
DefaultPort : integer = 1009; //默认主机端口
CHECKID : string = ''; //验证后的标志 'passok' 为通过,其它为没通过
VODDIR : string = 'd:/movie'; //默认影片目录
iSen : integer = 0; //iSen发送出去的长度
iSize : integer = 0; //文件长度 最好是全局变量
buf:array[1..MAX_LEN]of char;
senlen : integer = 0; //每次应该发送的长度
ret : integer = 0; //实际发送的文件长度
filen : file; //最好是全局变量
filelong :int64;
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
var
DirRoot : TTreenode;
begin
// 程序开始运行时激活服务器端Socket
ServerSocket1.Active := false;
ServerSocket1.Port := DefaultPort;
ServerSocket1.Active:= true;
Statusbar1.Panels.Items[0].Text:='服务器启动.主机名:'+ServerSocket1.Socket.LocalHost+' 监听端口:'+inttostr(ServerSocket1.Port);
self.Caption:=Statusbar1.Panels.Items[0].Text;
Application.Title:=Statusbar1.Panels.Items[0].Text;
Statusbar1.Panels.Items[1].Text := '在线用户数: '+IntToStr(ServerSocket1.Socket.ActiveConnections);
Statusbar1.Panels.Items[2].Text := '你的登录时间为:' + formatdatetime('yyyy年mm月dd日 hh:mm:ss',now);
DirRoot := TreeView1.Items.Add(nil, 'DirRoot');
//新建TreeView根结点
DirToTreeView(Treeview1,VODDIR,DirRoot,true);
//根据电影目录生成TreeView结构
TreeView1.FullExpand;
TreeView1.SaveToFile('c:/voddir.vod');
// filelong := filen.Size;
//上面两句,我本想将TreeView存入一个文件,然后将这个文件发过去的,但没做好
assignfile(filen, 'c:/voddir.vod');
reset(filen,1);
filelong:=filesize(filen);
closefile(filen);
// TreeView1.FullCollapse;
end;
procedure TForm1.ServerSocket1ClientConnect(Sender: TObject;
Socket: TCustomWinSocket);
Var
strIp,strHost:string;
Count:Integer;
begin
strIp:=Socket.RemoteAddress;
strHost:=Socket.RemoteHost;
Memo1.Lines.Add('当前登录用户');
Memo1.Lines.add(#9'SocketID:'+Inttostr(Socket.SocketHandle));
with DataModule1 do
begin
SqlDataSet1.Active := false;
SqlDataSet1.CommandType := ctQuery;
SqlDataSet1.CommandText := 'insert into logs (ipaddr,socketid,computer,logintime) values ('
+ '''' + strIP + '''' + ',' + '''' + inttostr(socket.socketHandle) + '''' + ',' + '''' + strHost + '''' + ',' + '''' + formatdatetime('yyyy-mm-dd hh:mm:ss',now) + '''' + ')';
//日志记录内容:当前客户机IP地址、SOCKET标识、计算机名、登录时间、
// showmessage(sqldataset1.CommandText); //调试,用于显示Sql语句
try
SqlDataSet1.ExecSQL(false);
// SqlDataSet1.Refresh;
except on E:exception do
begin
Messagebox(0,pchar('Log日志记录错误!'),pchar('提示'),MB_OK + MB_IconError + MB_SYSTEMMODAL);
// FlashWindow(form1.Handle,true);
exit;
end;
end;
end;
// Combox1.Items.Add(Inttostr(Socket.SocketHandle));
Memo1.lines.add(#9'IP地址:'+strIp);
Memo1.Lines.Add(#9'主机名:'+strHost);
Count := ServerSocket1.Socket.ActiveConnections; //Count得到当前连接的用户数
Statusbar1.Panels.Items[1].Text := '在线用户: '+IntToStr(Count);
end;
procedure sendvoddir;
var
fs: TFileStream;
s: string;
buf: array[0..bufsize-1] of char;
i, n, pos: integer;
ret, nBytes, nLeft, idx: integer;
begin
n := 0;
fs := TFileStream.Create('c:/voddir.vod', fmOpenRead); //打开一个文件
if not form1.ServerSocket1.Socket.Connections[0].Connected then exit; //如果客户端没有连接,那么退出
while fs.Position < fs.Size do //如果文件指针位置小于文件长度,那么说明还有数据要继续发送
begin
if (fs.Size - fs.Position) < bufsize then //判断是否是最后一次发送(因为最后一次流文件的长度可能不够1400字节)
pos := fs.Size - fs.Position //如果是,那么发送剩余的字节数
else
pos := bufsize; //否则发送1400个字节
FillChar(buf, bufsize, 0); //清零要发送的缓冲区
fs.ReadBuffer(buf, pos); //把文件内容读入缓冲区
//下面的while是保证数据能够正确发送的关键,可以防止数据缓冲区丢失数据
nLeft := bufsize;
idx := 0;
while nLeft > 0 do
begin
ret := form1.ServerSocket1.Socket.Connections[0].SendBuf(buf[idx], nLeft); //发送文件内容
if ret = -1 then //如果返回-1,说明发送错误
begin
//raise exception.Create('Sendbuf error'); //你也可以根据数据是否重要来决定是中断发送,
break; //还是跳过此次发送,而继续下次发送
end;
inc(idx, ret);
dec(nLeft, ret);
end;
inc; //发送次数,和客户端的RecvTotal对应
sleep(10);
end;
fs.Free;
end;
procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
///////////////////////////////////////////////////////////////////////////////
var
pchar;
length:longint;
Count,i:Integer;
tmpuser,tmppass : string;
tmpsocket : TCustomWinSocket;
begin
///////////////////////////////////////////////////////////////////////////////
p:=nil;
while socket.ReceiveLength > 0 do //如果接收缓冲区不为空,表示有信息收到
begin
length:=socket.receivelength; //记录接收缓冲区长度
Getmem(p,length); //为接收分配内存
TRY
socket.ReceiveBuf(p^,socket.receivelength); //接收到P指针的缓冲区中
Count:=ServerSocket1.Socket.ActiveConnections; //总的用户数加 1
// for i:=0 to Count-1 do
// ServerSocket1.Socket.Connections.SendBuf(p^,length);
//循环将消息发送给每个客户端
//如果接收到的是用户名和密码验证字串就进行验证
// showmessage('passid is :' + passid );
if (pos(passid,strpas(p)) > 0) and (length > 38) then
//用户名、密码验证前导标志8位,用户名15位,密码15位,共38位
begin
tmpuser := trimright(copy(strpas(p),9,15));
//取用户名
tmppass := trimright(copy(strpas(p),24,15));
//取口令字
// showmessage('user:' + tmpuser + ' ' + 'passwd:' + tmppass);
if checkpass(tmpuser,tmppass) //检查用户名和口令字是否符合
then
CHECKID := 'passok' //验证通过
else
begin
CHECKID := '123456'; //验证不通过
end;
socket.SendText(PASSID + CHECKID + FSIZEID + inttostr(Filelong) + #13#10);
if CHECKID = 'passok' then
sleep(100); //为了怕上次传输的合在一起,先暂停一下,但没有效果
SendVodDir;
//发送验证消息给客户端
end;
FINALLY
FreeMem(p);
END;
end;
end;
//当连接被接受的时候进行的处理
procedure TForm1.ServerSocket1Accept(Sender: TObject;
Socket: TCustomWinSocket);
var
Tempstrchar;
begin
TempStr:=pchar('欢迎登陆服务器 '#13#10);
// socket.SendText(TempStr);
//通常在这里需要处理一些什么事情
end;
function checkpass(userinfo,passinfo:string):boolean;
//对接收到的用户名和密码信息到数据中进行验证
begin
with DataModule1 do
begin
sqlqry_users.Active := false;
sqlqry_users.SQL.Add('select * from users ');
// where name=' + '''' + sqlqry_users.Params.ParamByName('name').Value + '''' + ' and passwd=' + '''' + sqlqry_users.Params.ParamByName('passwd').Value +'''';
sqlqry_users.Open;
//这里是在上面查询的时候加参数呢是在查询结果出来后再来查找适合的结果,哪种好,效率更高,个人倾向第一种
if sqlqry_users.Locate('name;passwd',VarArrayOf([userinfo,passinfo]),[loPartialKey]) then
//对指定的用户名和口令字在用户数据表中进行查找
begin //用户口令验证成功的处理
// showmessage('pass');
Result := true;
end
else
begin //用户口令验证失败的处理
// showmessage('not pass');
Result := false;
end;
end;
end;
//当出现Socket连接错误时进行的处理
procedure TForm1.ServerSocket1ClientError(Sender: TObject;
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
begin
//错误判断
Case ErrorCode Of
10054:Memo1.lines.add('连接被用户重置.');
Else
Memo1.Lines.Add('发生Socket错误,错误代码:'+InttoStr(errorCode));
// 显示错误码
End;
ErrorCode:=0;
Socket.Close;
end;
//当断开连接时的处理
procedure TForm1.ServerSocket1ClientDisconnect(Sender: TObject;
Socket: TCustomWinSocket);
Var
Count:Integer;
// IDIndex:Integer;
begin
Memo1.Lines.add('用户离线');
Memo1.Lines.add(' SocketID:'+Inttostr(Socket.SocketHandle));
// IDIndex:=Combox1.Items.IndexOf( Inttostr(Socket.SocketHandle));
// Combox1.Items.Delete(IDIndex);
//该事件在用户离开前发生
Count := ServerSocket1.Socket.ActiveConnections - 1; //当前用户总数减1
Statusbar1.Panels.Items[1].Text := '在线用户:' + Inttostr(Count); //更新状态栏
//将用户离线的时间登记到数据库中
end;
//将指定的目录及子目录下的文件信息返回到TreeView中
procedure DirToTreeView(ATreeView: TTreeView; ADirectory: string;
ARoot: TTreeNode; AIncludeFiles: Boolean);
//------------------------------------------------------------------------
//参数信息 :// 第一个是一个TreeView对象
// 第二个是指定的要取的目录名字
// 第三个是根结点的名字
// 第四个是指明是否包含文件还是只包含目录
//用法及调用格式
// DirRoot := TreeView1.Items.Add(nil, 'DirRoot');
// DirToTreeView(Treeview1,'d:/work',DirRoot,true);
//-------------------------------------------------------------------------
var
SearchRec : TSearchRec;
ItemTemp : TTreeNode;
begin
with ATreeView.Items do
try
BeginUpdate; //开始更新,使用BeginUpdate会使效率更高
if ADirectory[Length(ADirectory)] <> '/' then
ADirectory := ADirectory +'/';
if FindFirst(ADirectory + '*.*', faDirectory, SearchRec) = 0 then
begin
repeat
if (SearchRec.Attr and faDirectory = faDirectory) and (SearchRec.Name[1] <> '.') then
begin
if (SearchRec.Attr and faDirectory > 0) then
ARoot := AddChild(ARoot, SearchRec.Name);
ItemTemp := ARoot.Parent;
DirToTreeView(ATreeView, ADirectory + SearchRec.Name, ARoot, AIncludeFiles);
ARoot := ItemTemp;
end
else if AIncludeFiles then
if SearchRec.Name[1] <> '.' then
AddChild(ARoot, SearchRec.Name);
until FindNext(SearchRec) <> 0;
FindClose(SearchRec);
end;
finally
EndUpdate; //结束更新
end;
end;
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
VODDIR := EdtVodPath.Text;
DirToTreeView(Treeview1,VODDIR,self.TreeView1.GetNodeAt(0,0),true);
//根据电影目录生成TreeView结构
end;
procedure TForm1.BitBtn2Click(Sender: TObject);
begin
TreeView1.FullExpand;
end;
procedure TForm1.BitBtn3Click(Sender: TObject);
begin
TreeView1.FullCollapse;
end;
end.
------------------------------以上是服务端的程序-----------------------------
unit test_server;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Sockets, SUIButton, StdCtrls, SUIEdit, DBXpress, DB, SqlExpr,
IdBaseComponent, IdComponent, IdTCPServer, ScktComp, ComCtrls, ExtCtrls,
Grids, DBGrids, WinSkinData, WinSkinForm, Buttons;
type
TForm1 = class(TForm)
Panel1: TPanel;
StatusBar1: TStatusBar;
ServerSocket1: TServerSocket;
Memo1: TMemo;
DBGrid1: TDBGrid;
TreeView1: TTreeView;
WinSkinForm1: TWinSkinForm;
SkinData1: TSkinData;
ListBox1: TListBox;
EdtVodPath: TEdit;
BitBtn1: TBitBtn;
BitBtn2: TBitBtn;
BitBtn3: TBitBtn;
ProgressBar1: TProgressBar;
procedure FormCreate(Sender: TObject);
procedure ServerSocket1ClientConnect(Sender: TObject;
Socket: TCustomWinSocket);
procedure ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
procedure ServerSocket1Accept(Sender: TObject;
Socket: TCustomWinSocket);
procedure ServerSocket1ClientError(Sender: TObject;
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
procedure ServerSocket1ClientDisconnect(Sender: TObject;
Socket: TCustomWinSocket);
procedure BitBtn1Click(Sender: TObject);
procedure BitBtn2Click(Sender: TObject);
procedure BitBtn3Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
const
UniqueAppstr='I_AM_UNIQUE_APP';
PASSID = '!$@%*#^('; //用户名和密码传送前导标志
FSIZEID = '~!@#$%'; //文件长度前导标志
MAX_LEN = 2048;
ENDID = '@@@12@13@14@@41@31@21@@@'; //24位传输结束标志
bufsize = 1460; //缓冲区大小
var
Form1: TForm1;
function checkpass(userinfo,passinfo:string):boolean;
//验证口令字
procedure DirToTreeView(ATreeView: TTreeView; ADirectory: string;
ARoot: TTreeNode; AIncludeFiles: Boolean);
//把指定的目录返回到 TreeView 结构中
procedure SendVodDir;
//发送影片目录文件到客户端
implementation
uses U_DataModule1, U_adduser;
var
total_user : integer=0; //在线用户合计数
DefaultHost : string = '192.168.0.2'; //默认主机地址
DefaultPort : integer = 1009; //默认主机端口
CHECKID : string = ''; //验证后的标志 'passok' 为通过,其它为没通过
VODDIR : string = 'd:/movie'; //默认影片目录
iSen : integer = 0; //iSen发送出去的长度
iSize : integer = 0; //文件长度 最好是全局变量
buf:array[1..MAX_LEN]of char;
senlen : integer = 0; //每次应该发送的长度
ret : integer = 0; //实际发送的文件长度
filen : file; //最好是全局变量
filelong :int64;
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
var
DirRoot : TTreenode;
begin
// 程序开始运行时激活服务器端Socket
ServerSocket1.Active := false;
ServerSocket1.Port := DefaultPort;
ServerSocket1.Active:= true;
Statusbar1.Panels.Items[0].Text:='服务器启动.主机名:'+ServerSocket1.Socket.LocalHost+' 监听端口:'+inttostr(ServerSocket1.Port);
self.Caption:=Statusbar1.Panels.Items[0].Text;
Application.Title:=Statusbar1.Panels.Items[0].Text;
Statusbar1.Panels.Items[1].Text := '在线用户数: '+IntToStr(ServerSocket1.Socket.ActiveConnections);
Statusbar1.Panels.Items[2].Text := '你的登录时间为:' + formatdatetime('yyyy年mm月dd日 hh:mm:ss',now);
DirRoot := TreeView1.Items.Add(nil, 'DirRoot');
//新建TreeView根结点
DirToTreeView(Treeview1,VODDIR,DirRoot,true);
//根据电影目录生成TreeView结构
TreeView1.FullExpand;
TreeView1.SaveToFile('c:/voddir.vod');
// filelong := filen.Size;
//上面两句,我本想将TreeView存入一个文件,然后将这个文件发过去的,但没做好
assignfile(filen, 'c:/voddir.vod');
reset(filen,1);
filelong:=filesize(filen);
closefile(filen);
// TreeView1.FullCollapse;
end;
procedure TForm1.ServerSocket1ClientConnect(Sender: TObject;
Socket: TCustomWinSocket);
Var
strIp,strHost:string;
Count:Integer;
begin
strIp:=Socket.RemoteAddress;
strHost:=Socket.RemoteHost;
Memo1.Lines.Add('当前登录用户');
Memo1.Lines.add(#9'SocketID:'+Inttostr(Socket.SocketHandle));
with DataModule1 do
begin
SqlDataSet1.Active := false;
SqlDataSet1.CommandType := ctQuery;
SqlDataSet1.CommandText := 'insert into logs (ipaddr,socketid,computer,logintime) values ('
+ '''' + strIP + '''' + ',' + '''' + inttostr(socket.socketHandle) + '''' + ',' + '''' + strHost + '''' + ',' + '''' + formatdatetime('yyyy-mm-dd hh:mm:ss',now) + '''' + ')';
//日志记录内容:当前客户机IP地址、SOCKET标识、计算机名、登录时间、
// showmessage(sqldataset1.CommandText); //调试,用于显示Sql语句
try
SqlDataSet1.ExecSQL(false);
// SqlDataSet1.Refresh;
except on E:exception do
begin
Messagebox(0,pchar('Log日志记录错误!'),pchar('提示'),MB_OK + MB_IconError + MB_SYSTEMMODAL);
// FlashWindow(form1.Handle,true);
exit;
end;
end;
end;
// Combox1.Items.Add(Inttostr(Socket.SocketHandle));
Memo1.lines.add(#9'IP地址:'+strIp);
Memo1.Lines.Add(#9'主机名:'+strHost);
Count := ServerSocket1.Socket.ActiveConnections; //Count得到当前连接的用户数
Statusbar1.Panels.Items[1].Text := '在线用户: '+IntToStr(Count);
end;
procedure sendvoddir;
var
fs: TFileStream;
s: string;
buf: array[0..bufsize-1] of char;
i, n, pos: integer;
ret, nBytes, nLeft, idx: integer;
begin
n := 0;
fs := TFileStream.Create('c:/voddir.vod', fmOpenRead); //打开一个文件
if not form1.ServerSocket1.Socket.Connections[0].Connected then exit; //如果客户端没有连接,那么退出
while fs.Position < fs.Size do //如果文件指针位置小于文件长度,那么说明还有数据要继续发送
begin
if (fs.Size - fs.Position) < bufsize then //判断是否是最后一次发送(因为最后一次流文件的长度可能不够1400字节)
pos := fs.Size - fs.Position //如果是,那么发送剩余的字节数
else
pos := bufsize; //否则发送1400个字节
FillChar(buf, bufsize, 0); //清零要发送的缓冲区
fs.ReadBuffer(buf, pos); //把文件内容读入缓冲区
//下面的while是保证数据能够正确发送的关键,可以防止数据缓冲区丢失数据
nLeft := bufsize;
idx := 0;
while nLeft > 0 do
begin
ret := form1.ServerSocket1.Socket.Connections[0].SendBuf(buf[idx], nLeft); //发送文件内容
if ret = -1 then //如果返回-1,说明发送错误
begin
//raise exception.Create('Sendbuf error'); //你也可以根据数据是否重要来决定是中断发送,
break; //还是跳过此次发送,而继续下次发送
end;
inc(idx, ret);
dec(nLeft, ret);
end;
inc; //发送次数,和客户端的RecvTotal对应
sleep(10);
end;
fs.Free;
end;
procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
///////////////////////////////////////////////////////////////////////////////
var
pchar;
length:longint;
Count,i:Integer;
tmpuser,tmppass : string;
tmpsocket : TCustomWinSocket;
begin
///////////////////////////////////////////////////////////////////////////////
p:=nil;
while socket.ReceiveLength > 0 do //如果接收缓冲区不为空,表示有信息收到
begin
length:=socket.receivelength; //记录接收缓冲区长度
Getmem(p,length); //为接收分配内存
TRY
socket.ReceiveBuf(p^,socket.receivelength); //接收到P指针的缓冲区中
Count:=ServerSocket1.Socket.ActiveConnections; //总的用户数加 1
// for i:=0 to Count-1 do
// ServerSocket1.Socket.Connections.SendBuf(p^,length);
//循环将消息发送给每个客户端
//如果接收到的是用户名和密码验证字串就进行验证
// showmessage('passid is :' + passid );
if (pos(passid,strpas(p)) > 0) and (length > 38) then
//用户名、密码验证前导标志8位,用户名15位,密码15位,共38位
begin
tmpuser := trimright(copy(strpas(p),9,15));
//取用户名
tmppass := trimright(copy(strpas(p),24,15));
//取口令字
// showmessage('user:' + tmpuser + ' ' + 'passwd:' + tmppass);
if checkpass(tmpuser,tmppass) //检查用户名和口令字是否符合
then
CHECKID := 'passok' //验证通过
else
begin
CHECKID := '123456'; //验证不通过
end;
socket.SendText(PASSID + CHECKID + FSIZEID + inttostr(Filelong) + #13#10);
if CHECKID = 'passok' then
sleep(100); //为了怕上次传输的合在一起,先暂停一下,但没有效果
SendVodDir;
//发送验证消息给客户端
end;
FINALLY
FreeMem(p);
END;
end;
end;
//当连接被接受的时候进行的处理
procedure TForm1.ServerSocket1Accept(Sender: TObject;
Socket: TCustomWinSocket);
var
Tempstrchar;
begin
TempStr:=pchar('欢迎登陆服务器 '#13#10);
// socket.SendText(TempStr);
//通常在这里需要处理一些什么事情
end;
function checkpass(userinfo,passinfo:string):boolean;
//对接收到的用户名和密码信息到数据中进行验证
begin
with DataModule1 do
begin
sqlqry_users.Active := false;
sqlqry_users.SQL.Add('select * from users ');
// where name=' + '''' + sqlqry_users.Params.ParamByName('name').Value + '''' + ' and passwd=' + '''' + sqlqry_users.Params.ParamByName('passwd').Value +'''';
sqlqry_users.Open;
//这里是在上面查询的时候加参数呢是在查询结果出来后再来查找适合的结果,哪种好,效率更高,个人倾向第一种
if sqlqry_users.Locate('name;passwd',VarArrayOf([userinfo,passinfo]),[loPartialKey]) then
//对指定的用户名和口令字在用户数据表中进行查找
begin //用户口令验证成功的处理
// showmessage('pass');
Result := true;
end
else
begin //用户口令验证失败的处理
// showmessage('not pass');
Result := false;
end;
end;
end;
//当出现Socket连接错误时进行的处理
procedure TForm1.ServerSocket1ClientError(Sender: TObject;
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
begin
//错误判断
Case ErrorCode Of
10054:Memo1.lines.add('连接被用户重置.');
Else
Memo1.Lines.Add('发生Socket错误,错误代码:'+InttoStr(errorCode));
// 显示错误码
End;
ErrorCode:=0;
Socket.Close;
end;
//当断开连接时的处理
procedure TForm1.ServerSocket1ClientDisconnect(Sender: TObject;
Socket: TCustomWinSocket);
Var
Count:Integer;
// IDIndex:Integer;
begin
Memo1.Lines.add('用户离线');
Memo1.Lines.add(' SocketID:'+Inttostr(Socket.SocketHandle));
// IDIndex:=Combox1.Items.IndexOf( Inttostr(Socket.SocketHandle));
// Combox1.Items.Delete(IDIndex);
//该事件在用户离开前发生
Count := ServerSocket1.Socket.ActiveConnections - 1; //当前用户总数减1
Statusbar1.Panels.Items[1].Text := '在线用户:' + Inttostr(Count); //更新状态栏
//将用户离线的时间登记到数据库中
end;
//将指定的目录及子目录下的文件信息返回到TreeView中
procedure DirToTreeView(ATreeView: TTreeView; ADirectory: string;
ARoot: TTreeNode; AIncludeFiles: Boolean);
//------------------------------------------------------------------------
//参数信息 :// 第一个是一个TreeView对象
// 第二个是指定的要取的目录名字
// 第三个是根结点的名字
// 第四个是指明是否包含文件还是只包含目录
//用法及调用格式
// DirRoot := TreeView1.Items.Add(nil, 'DirRoot');
// DirToTreeView(Treeview1,'d:/work',DirRoot,true);
//-------------------------------------------------------------------------
var
SearchRec : TSearchRec;
ItemTemp : TTreeNode;
begin
with ATreeView.Items do
try
BeginUpdate; //开始更新,使用BeginUpdate会使效率更高
if ADirectory[Length(ADirectory)] <> '/' then
ADirectory := ADirectory +'/';
if FindFirst(ADirectory + '*.*', faDirectory, SearchRec) = 0 then
begin
repeat
if (SearchRec.Attr and faDirectory = faDirectory) and (SearchRec.Name[1] <> '.') then
begin
if (SearchRec.Attr and faDirectory > 0) then
ARoot := AddChild(ARoot, SearchRec.Name);
ItemTemp := ARoot.Parent;
DirToTreeView(ATreeView, ADirectory + SearchRec.Name, ARoot, AIncludeFiles);
ARoot := ItemTemp;
end
else if AIncludeFiles then
if SearchRec.Name[1] <> '.' then
AddChild(ARoot, SearchRec.Name);
until FindNext(SearchRec) <> 0;
FindClose(SearchRec);
end;
finally
EndUpdate; //结束更新
end;
end;
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
VODDIR := EdtVodPath.Text;
DirToTreeView(Treeview1,VODDIR,self.TreeView1.GetNodeAt(0,0),true);
//根据电影目录生成TreeView结构
end;
procedure TForm1.BitBtn2Click(Sender: TObject);
begin
TreeView1.FullExpand;
end;
procedure TForm1.BitBtn3Click(Sender: TObject);
begin
TreeView1.FullCollapse;
end;
end.
------------------------------以上是服务端的程序-----------------------------