68_用Delphi编写局域网中的TCP聊天程序
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
用Delphi编写局域网中C/S型聊天程序
中原工学院计算机教研室夏敏捷
Internet盛行的今天,网上聊天QQ已成为一种时尚。QQ是深圳腾讯公司的一个网络实时通讯软件,在国内拥有大量的用户群。但QQ必须连接上互联网登陆到腾讯的服务器才能使用。所以我们可以自己写一个在局部网里面使用的自己的QQ。
QQ使用的是UDP协议,这是一种无连接协议,即通信双方不用建立连接就可以发送信息,所以效率比较高。Delphi本身自带的FastNEt公司的NMUDP控件就是一个UDP协议的用户数据报控件。这里我们编写的局域网上实现聊天的程序采用的是TCP协议,TCP 是一种面向连接协议,具有较高的可靠性。在Delphi中利用ClientSocket、ServerSocket这两种控件(Internet面板上),可以轻松的编写出C/S聊天程序,以下的程序在Delphi 6+winXP 中通过。
一、原理
首先建立客户与主机的连接,把要发送的文字信息写进字符串中,然后ClientSocket组件的Socket..sendtext方法把文本发送出去。当主机有数据接收时,触发它的ServerSocket 组件onClientRead事件,我们在这里用socket.ReceiveText接收字符信息,然后显示出来。主机可以通过Socket..sendtext方法再将此用户信息转发给所有用户或单独的用户,在数据到达客户端后触发客户端OnRead事件,接受主机的数据。
为了区分不同的信息(新用户信息、昵称、交谈、用户离开)设计了以下协议格式:1.发送添加的新用户信息的格式:
“添加用户”@用户的昵称^它的IP@用户的昵称^它的IP@……@
此信息中将所有的用户的昵称和它的IP均包含在其中,新用户是最后一个。
2.发送昵称信息的格式:
“昵称”@用户的昵称
此信息用于在客户和服务器建立连接后,发送用户的昵称给服务器。而用户的IP 地址可以通过(socket.RemoteAddress)得出。
3.发送文本对话信息的格式:
“交谈”@to用户的昵称@交谈的内容
4.发送离开信息的格式:
“离开”@离开的用户的昵称
二、客户端:
新建一个工程,在Internet面板拖一个ClientSocket控件到窗口,然后依次放上一个EDIT, 一个ListBox和一个RichEdit,两个按钮,一个状态条StatusBar1。当用户点击“连接主机”按钮时,用户输入服务器主机的IP及紧接着自己的昵称。
procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word;Shift: TShiftState); begin
if key=13 then //最好加本地IP
begin
if listbox1.itemindex>=0 then
begin
clientsocket1.Socket.SendText('交谈@'+'to'+listBox1.Items.strings[listbox1.itemindex]+'@ '+edit1.Text );
edit1.text:='';
end
else
showmessage('请选择交谈对象');
end;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
clientsocket1.Active :=false;
clientsocket1.close;
end;
procedure TForm1.Button1Click(Sender: TObject);
var str1:string;
begin
str1:=inputbox('建立连接','请输入IP','127.0.0.1');
if trim(str1)<>'' then
begin
clientsocket1.Port:=5555;//server port
clientsocket1.host:=str1;
try
clientsocket1.active:=true;
str1:=inputbox('建立连接','请输入昵称','泡泡');
clientsocket1.Socket.SendText('昵称@'+str1);
except
showmessage('连接失败');
end;
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
close;
end;
procedure TForm1.ClientSocket1Connect(Sender: TObject;Socket: TCustomWinSocket); begin
StatusBar1.SimpleText:='连接成功';
end;
procedure TForm1.ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
var str1,name,str2,nei_rong:string;
n,i:integer;
begin
str1:=socket.ReceiveText;
str2:=copy(str1,1,pos('@',str1)-1);
if str2='添加用户' then
begin
listbox1.Clear;//清除已有名单
str1:=copy(str1,pos('@',str1)+1,length(str1)-pos('@',str1));
while str1<>'' do //建立新名单
begin
name:=copy(str1,1,pos('@',str1)-1);//昵称^IP
listbox1.Items.Add(copy(name,1,pos('^',name)-1));
str1:=copy(str1,pos('@',str1)+1,length(str1)-pos('@',str1));
end;
RichEdit1.Lines.Add(name+'进入了');
end;
if str2='交谈' then //交谈@xmj@hello
begin
str2:=copy(str1,pos('@',str1)+1,length(str1)-pos('@',str1));
name:=copy(str2,1,pos('@',str2)-1);
nei_rong:=copy(str2,pos('@',str2)+1,length(str2)-pos('@',str2));
RichEdit1.Lines.Add(name+'对你说'+nei_rong);
end;
if str2='离开' then
begin
n:= pos('@',str1);
name:=copy(str1,n+1,length(str1)-n);
for i:=0 to listbox1.items.count-1 do
begin
if listbox1.items.strings[i]=name then
listbox1.items.delete(i);
end;
end;
end;
end.
三、服务器端:
新建一个工程,在Internet面板拖一个ServerSocket控件到窗口,然后依次放上一个EDIT, 一个ListView(ViewStyle属性为vsReport,表格型)和一个RichEdit,一个状态条StatusBar1。