最近学习局域网聊天程序,发现在线人较多(5-6个同时在线)的时候很容易出现程序死掉。
程序结构是这样的:
用一个TIdUDPServer监听端口,用一个timer每个几秒种广播一次在线,TIdUDPServer既做客户端又做服务端,发现很容易死掉,比如同时在线几个人,我在某台机器上发,另外的机上很容易死掉,这里的死掉是鼠标点击无响应,只能通过任务管理器关闭进程,对网络只知皮毛,恳请大家多多指教
程序结构是这样的:
用一个TIdUDPServer监听端口,用一个timer每个几秒种广播一次在线,TIdUDPServer既做客户端又做服务端,发现很容易死掉,比如同时在线几个人,我在某台机器上发,另外的机上很容易死掉,这里的死掉是鼠标点击无响应,只能通过任务管理器关闭进程,对网络只知皮毛,恳请大家多多指教
解决方案 »
- delphi中,事件句柄能否对应多个事件处理过程?
- 视频会议系统全国统一最低价4000元/套
- 请教! 什么是三层数据库啊 ,我不懂,请从简单说起!谢谢
- *******如何控制QQ的动行?******
- Wallpaper Calendar这样的效果如何实现
- 如何向.res文件中添加资源?
- HTML文件的预览
- 关于数据加入不成功
- 一个窗体form1,一个button1,一个query1, 一个datasource1。在button1按扭的代码中怎样来实现:
- 为什么我用的PCI专串口卡delphi不认啊!
- 求梦幻西游屏幕汉字识别代码
- 问一个简单问题,如何读写cxgrid中的cxGridBandedTableView中的数据?
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient,
StdCtrls, ExtCtrls, ScktComp, IdUDPBase, IdUDPClient,IdSocketHandle,
IdUDPServer, XPMan, ComCtrls;Const
CPort=5966;type
TFrmChar = class(TForm)
EdSpeek: TEdit;
Label1: TLabel;
CBxOnlineMan: TComboBox;
Label2: TLabel;
GBxList: TGroupBox;
MmText: TMemo;
GBxBody: TGroupBox;
LBxLineMan: TListBox;
BtnSend: TButton;
UServer: TIdUDPServer;
CheckBody: TTimer;
procedure CheckBodyTimer(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure UServerUDPRead(Sender: TObject; AData: TStream;
ABinding: TIdSocketHandle);
procedure FormDestroy(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure BtnSendClick(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure CBxOnlineManDropDown(Sender: TObject);
procedure FormKeyUp(Sender: TObject; var Key: Word;
Shift: TShiftState);
procedure LBxLineManDblClick(Sender: TObject);
private
ExitFlag:boolean;
OnlineList:TStrings;
procedure ASendMessage(AHost:string;AMessage:string);
Procedure onlineMes(const Amessage:string);
{ Private declarations }
public
{ Public declarations }
end;var
FrmChar: TFrmChar;implementation{$R *.dfm}
Procedure TFrmChar.onlineMes(const Amessage:string);
begin
try
if not Userver.BroadcastEnabled then
Userver.BroadcastEnabled:=True;
UServer.Broadcast(AMessage,CPort);
except
Exit;
end;
end;procedure TFrmChar.CheckBodyTimer(Sender: TObject);
begin
LbxLineMan.Clear;
if ExitFlag then
begin
Self.Close;
exit;
end;
OnlineMes('*Is On line*;'+UServer.LocalName);
end;procedure TFrmChar.FormCreate(Sender: TObject);
begin
try
UServer.DefaultPort:=CPort;
UServer.Active:=true;
except
Application.MessageBox('由于某种原因导致网络启动失败!','错误',MB_OK+MB_ICONERROR);
end;
OnlineList:=TStringList.create;
end;procedure TFrmChar.UServerUDPRead(Sender: TObject; AData: TStream;
ABinding: TIdSocketHandle);
var
RemoString,RecString,Cmd:String;
SBuffer:Array [0..1024] of char;
begin
remostring:='';
RecString:='';
SBuffer:='';
AData.Read(SBuffer,Adata.Size);
RecString:=trim(SBuffer);
if Pos('*Is On line*',RecString) > 0 then
begin
RemoString:=copy(RecString,Pos(';',RecString)+1,Length(RecString));
ASendmessage(Remostring,'*OnLine*;'+Userver.LocalName);
end; if Pos('*FirstLogin*',RecString) > 0 then
begin
RemoString:=copy(RecString,Pos(';',RecString)+1,Length(RecString));
Mmtext.Lines.Add(RemoString+' 上线了!');
Application.Restore;
Application.BringToFront;
end; if Pos('*OnLine*',RecString) > 0 then
begin
remostring:=copy(RecString,Pos('*;',RecString)+2,Length(RecString));
if pos(remostring,LbxLineman.Items.Text)> 0 then
exit;
LbxLineMan.Items.Add(RemoString);
end; if pos('*Speek*',Recstring) > 0 then
begin
Recstring:=copy(RecString,Pos('*;',RecString)+2,Length(RecString)); //dele speek
remoString:=copy(Recstring,0,Pos('*;',RecString)-1); //get remodeserver
Recstring:=copy(RecString,Pos('*;',RecString)+2,Length(RecString));
if Remostring <> UServer.LocalName then
begin
if pos('!*Command*!',Recstring)>0 then
begin
cmd:=Copy(RecString,Pos('!*Command*! ',RecString)+11,Length(RecString));
if pos('Exit',Cmd)>0 then
begin
ExitFlag:=true;
CHeckBody.Enabled:=false;
CheckBody.Interval:=500;
CheckBody.Enabled:=true;
Exit;
end;
end;
Mmtext.Lines.Add(remostring+' 对你说:['+' 时间:'+DatetimeTostr(Now)+']');
Mmtext.Lines.Add(Recstring);
Application.Restore;
Application.BringToFront;
end;
end; if pos('*Quit*',Recstring) > 0 then
begin
remostring:=copy(RecString,Pos('*;',RecString)+2,Length(RecString));
Mmtext.Lines.Add(remoString+' 离开了!');
LbxLineMan.Items.Delete(LbxLineMan.Items.IndexOf(remostring));
end;end;procedure TFrmChar.FormDestroy(Sender: TObject);
begin
OnlineList.Free;
end;procedure TFrmChar.FormShow(Sender: TObject);
begin
LbxLineMan.Clear;
OnlineMes('*FirstLogin*;'+Userver.LocalName);
onlineMes('*Is On line*;'+UServer.LocalName);
end;procedure TFrmChar.ASendMessage(AHost:string;AMessage:string);
begin
try
Userver.Send(AHost,Cport,AMessage);
except
exit;
end;
end;procedure TFrmChar.BtnSendClick(Sender: TObject);
var
AMessage:string;
begin
if CBXOnlineMan.Text = '' then
begin
Showmessage('请选择接收者!');
exit;
end;
if EDSpeek.Text = '' then
begin
Showmessage('不能发送空信息!');
exit;
end;
AMessage:='*Speek*;'+UServer.LocalName+'*;'+EDSpeek.Text;
if CbxOnlineMan.Text = '所有人' then
onlineMes(AMessage)
else
ASendMessage(CBXOnlineMan.Text,AMessage);
Mmtext.Lines.Add('你对 '+CBXOnlineMan.Text+' 说:['+' 时间:'+datetimetostr(now)+']');
Mmtext.Lines.Add(EDSpeek.Text);
EDSpeek.Clear;
Application.Minimize;
end;procedure TFrmChar.FormClose(Sender: TObject; var Action: TCloseAction);
begin
onlineMes('*Quit*;'+UServer.LocalName);
UServer.Active:=false;
end;procedure TFrmChar.CBxOnlineManDropDown(Sender: TObject);
begin
CBxOnlineMan.Items.Assign(LbxLineMan.Items);
CbxOnlineMan.Items.Add('所有人');
end;procedure TFrmChar.FormKeyUp(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if (key=13) and ((GetKeyState(VK_CONTROL) and ($F0000000))<>0)then
begin
BtnSendClick(nil);
end;
end;procedure TFrmChar.LBxLineManDblClick(Sender: TObject);
begin
if LbxLineMan.Count > 0 then
begin
CbxOnlineMan.Clear;
CbxOnlineMan.Items.Assign(LbxLineMan.Items);
CbxOnlineMan.ItemIndex:=LbxLineMan.ItemIndex;
end;
end;end.