![]() |
|
||||||||||||||
| | 网站首页 | 数据库教程 | web编程 | 服务器 | 程序设计 | | ||
|
||
|
||||||
| 简单网络聊天室实现 | ||||||
作者:佚名 文章来源:不详 点击数: 更新时间:2007-9-12 ![]() |
||||||
|
简单网络聊天室实现
--------------------------------------- by clin003 from http://clin003.com/或http://blog.csdn.net/clin003/ --------------------------------------- 学习目的: 初步认识网络编程概念 认识tcp/ip网络通讯的简单实现过程 认识线程的类型的声明及实现 设计一个简单的S/C模式结合的聊天程序 进一步认识组件的使用 代码实现部分 定义一个线程类型tclientdatathread,用来实现向infomemo组件异步写入交谈双方的内容。
type TClientDataThread=class(TThread) private public listBuffer:tStringList; //缓存区,缓存远程发送的当前聊天信息 TargetList:tStrings; //聊天的信息存放 procedure synchAddDataToControl; //同步执行过程 Constructor Execute;override; //重载线程类的执行函数 Procedure Terminate; //用于结束线程,释放资源 end 线程类型中的方法具体实现部分: Constructor TclientDataThread.Create(CreateSuspended:Boolean); begin inherited create(createSuspended); FreeOnTerminate:=true; //线程结束时自动释放资源 ListBuffer:=TstringList.Create; //创建字符串列表变量,作为缓存区 end; Procedure TClientDataThread.Terminate; begin ListBuffer.Free; //释放字符串列表所占资源,即释放缓存区 inherited; end; Procedure TClientDataThread.Execute; begin Synchronize(synchAddDataToControl); //同步处理字符串的操作 end; procedure TclientDataThread.synchAddDataToControl; begin TargetList.AddStrings(ListBuffer); //想TargetList中添加缓存区新的字符串 end; 为了获得用户当前机器的ip地址,在主框体的OnCreate事件中添加代码: procedure TForm1.FormCreate(Sender: TObject); var HostName,HostIp:string; begin HostName:=TcpServer1.LookupHostName('127.0.0.1');//获得主机名称 HostIp:=TcpServer1.LookupHostAddr(HostName); //获得主机ip地址 StatusBar1.Panels[0].Text:='我的ip:'+HostIP; //在状态栏第一项显示ip end; 设置服务器的参数,按钮的onclick事件代码: procedure TForm1.Button2Click(Sender: TObject); begin TcpServer1.LocalPort:=edit2.Text; //设置服务器端口 TcpServer1.Active:=ture; //激活服务器 sendmemo.SetFocus; //将焦点定位于信息输入区域 end; 为发送按钮添加代码,用以发送交谈内容: procedure TForm1.Button1Click(Sender: TObject); var i:integer; begin TcpClient1.RemoteHost:=edit1.Text; //设置对方主机名 TcpClient1.RemotePort:=edit2.Text; //对方主机端口号 try if TcpClient1.Connect then //如果已经建立连接 for i:=0 to sendmemo.Lines.Count-1 do TcpClient1.Sendln(sendmemo.Lines[i]);//发送信息输入区域的文本 finally tcpclient1.Disconnect; //信息发送完毕,暂时断开socket连接、 end; sendmemo.SetFocus; //将焦点定位于信息输入区域 end; tcpserver接到socket连接请求时自动触发onaccept事件。下边是onaccept事件代码,将接收到的信息增加到infomemo组件中,并将连接情况显示在状态栏的第二项。 procedure TForm1.TcpServer1Accept(Sender: TObject; ClientSocket: TCustomIpClient); var s:string; DataThread:TclientDataThread; begin //本地服务器探测到新的消息,开始创建一个新的线程 DataThread:=TclientDataThread.Create(True); //在信息显示框中显示对方的消息 DataThread.TargetList:=infomemo.Lines; //在状态栏第二项中显示对方的主机名和ip地址 statusBar1.Panels[1].Text:='连接到' + clientsocket.LookupHostName(clientsocket.RemoteHost)+'(' +clientsocket.RemoteHost+')'; //接受对方消息,并保存到缓冲区ListBuffer中 DataThread.listBuffer.Add('==begin=='); s:=clientsocket.Receiveln; while s<>'' do //获得对方发来的消息 begin datathread.listBuffer.Add(s); s:=clientsocket.Receiveln; end; dataThread.listBuffer.Add('===end==='); //继续执行线程,把listbuffer中的消息写入TargetList,即infomemo组件 DataThread.Resume; end; 为啦显示socket连接的状态,需要在tcpclient组件的onsend事件中,向状态栏输出提示信息: procedure TForm1.TcpClient1Send(Sender: TObject; Buf: PAnsiChar; var DataLen: Integer); begin statusbar1.Panels[2].Text:='发送信息'+inttostr(DataLen)+'个字符'; end; 关于线程的概念: Win32操作系统提供了在应用程序中执行多线程的能力。从16位的Windows升级到Win32的一个最 大受益便是:它允许多线程同时运行。 线程是一种操作系统对象,它表示在进程中代码的一 条执行路径。在每一个Win32的应用程序中都至少有一个线程,它通常被称为主线程或默认线程。在 应用程序中也可以自由地创建别的线程去执行其他任务。 线程技术使不同的代码可以同时运行。当然,只有在多C P U的计算机上,多个线程才能够真正地 同时运行。然而,由于操作系统把C P U的时间分成很短的片段分配给每个线程,这样给人的感觉好像 是多个线程真的同时运行。 Win32是一种抢占式操作系统,在抢占式多任务环境中,操作系统负责管理哪个线程在什么时候执行。如果当 线程1暂停执行时,线程2才有机会获得C P U时间,我们说线程1是抢占的。如果某个线程的代码陷入 死循环,这并不可怕,操作系统仍会安排时间给其他线程。 对比协作式操作系统,在Windows 3.1下,程序员必须保证应用程序能够把控制权返还给Windows。如果这一步失败,将 导致整个操作环境锁死,或许你已经有过这样的痛苦经历。只要稍微想想便会明白, 16位的Windows 是如此脆弱,它依赖于应用程序的运行情况,并且不允许程序陷入死循环或无穷递归以及任何封闭状 态。这是因为所有的应用程序都必须协助Windows工作,这种工作类型被称为协作式多任务系统。 在Delphi程序中使用多线程 对一个Windows程序员来说,线程提供了非常大的好处。可以在应用程序中的任何地方创建多个 附属线程,它们在后台进行各种类型的处理。 本文来源:http://blog.csdn.net/clin003/archive/2007/09/05/1772583.aspx
|
||||||
| 文章录入:admin 责任编辑:admin | ||||||
| 【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口】 | ||||||
| 网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!) |
| | 设为首页 | 加入收藏 | 联系站长 | 友情链接 | 版权申明 | 网站公告 | 网站地图 | 管理登录 | | |||
|