📄 20000924006.htm
字号:
<tr>
<td>ServerType</td>
<td> </td>
<td>服务类型,参见TServerSocket->ServerType。</td>
</tr>
<tr>
<td>ActiveConnection</td>
<td>int</td>
<td>只读,返回当前活动的连接数。</td>
</tr>
<tr>
<td>Connection</td>
<td>TCustomWinSocket</td>
<td>数组,索引n表示第n+1个连接,如Connection[0]表示第一个连接。</td>
</tr>
</tbody>
</table>
<p>有了这些知识,我们就可以完成一些基本的WinSocket编程了,下面就结合一个简单的闲聊程序来看看具体的应用。</p>
<p>首先在窗体上放置以下VCL组件,并修改相应属性:</p>
<table
cellpadding=0 cellspacing=0 width="100%">
<tbody>
<tr>
<td width="13%">类型</td>
<td width="10%">Name属性</td>
<td width="17%">Caption/Text</td>
<td width="60%">说明</td>
</tr>
<tr>
<td width="13%">TCheckBox</td>
<td width="10%">ckListen</td>
<td width="17%">监听</td>
<td width="60%">当选取时,本程序作为服务器</td>
</tr>
<tr>
<td width="13%">TCheckBox</td>
<td width="10%">ckConnect</td>
<td width="17%">连接</td>
<td width="60%">当选取时,本程序作为客户机</td>
</tr>
<tr>
<td width="13%">TEdit</td>
<td width="10%">edName</td>
<td width="17%">无名氏</td>
<td width="60%">闲聊时所用的名字。</td>
</tr>
<tr>
<td width="13%">TBitBtn</td>
<td width="10%">bbtSave</td>
<td width="17%">&S保存</td>
<td width="60%">单击时保存谈话内容</td>
</tr>
<tr>
<td width="13%">TBitBtn</td>
<td width="10%">bbtClose</td>
<td width="17%">&C关闭</td>
<td width="60%">单击时关闭此窗口(设置Kind=bkClose)</td>
</tr>
<tr>
<td width="13%">TEdit</td>
<td width="10%">edTalk</td>
<td width="17%"> </td>
<td width="60%">在此输入谈话内容</td>
</tr>
<tr>
<td width="13%">TMemo</td>
<td width="10%">mmTalk</td>
<td width="17%"> </td>
<td width="60%">在此显示谈话内容</td>
</tr>
<tr>
<td width="13%">TServerSocket</td>
<td width="10%">ServerSocket1</td>
<td width="17%"> </td>
<td width="60%">作服务器时使用(设置Port=2222)</td>
</tr>
<tr>
<td width="13%">TClientSocket</td>
<td width="10%">ClientSocket1</td>
<td width="17%"> </td>
<td width="60%">作为客户时使用(设置Port=2222)</td>
</tr>
<tr>
<td width="13%">TSaveDialog</td>
<td width="10%">sdTalk</td>
<td width="17%"> </td>
<td
width="60%">保存文件时的选项(设置DefaultExt="*.txt",Filter=文本文件(*.TXT)|*.txt|所有文件(*.*)|*.*)。</td>
</tr>
<tr>
<td width="13%">TStatusBar</td>
<td width="10%">StatusBar1</td>
<td width="17%"> </td>
<td width="60%">用于显示一些提示信息,只要在属性"Pannels"中加一栏即可</td>
</tr>
</tbody>
</table>
<p>程序作为服务器的设置:<br>
当单击"监听"时,如果没有监听则开始监听,在提示栏中显示"监听",并把"连接"这个复选框无效。如果已经监听,则取消监听,并使"连接"这个复选框有效。所以,在ckListen的OnClick事件中加入以下代码:<br>
<br>
<br>
if(ServerSocket1->Active)<br>
{ <br>
ServerSocket1->Active=false;<br>
ckListen->Checked=false; <br>
StatusBar1->Panels->Items[0]->Text="";<br>
} <br>
else <br>
{<br>
ServerSocket1->Active=true; <br>
ckListen->Checked=true;<br>
ClientSocket1->Active=false;<br>
StatusBar1->Panels->Items[0]->Text="监听..."
;<br>
} <br>
ckConnect->Enabled=!(ckListen->Checked);<br>
<br>
当有客户加入时,向所有的客户发出通知:并在自已的mmTalk加入此消息:所以在ServerSocket1的OnAccept事件中加入如下代码:<br>
<br>
int i;<br>
AnsiString str1="服务器消息:"+Socket->RemoteHost+"加入";<br>
for(i=0;i<ServerSocket1->Socket->ActiveConnections;i++)<br>
ServerSocket1->Socket->Connections[i]->SendText("服务器消息:"+Socket->RemoteHost+"加入");<br>
StatusBar1->Panels->Items[0]->Text=str1;<br>
mmTalk->Lines->Add(str1);<br>
<br>
当客户机通知服务器读信息时,首先读出字符串,然后把读到的字符串发送到每一台连接的客户,并在自已的mmTalk中加入客户发送来的字符串。所以,在TServerSocket的OnClientRead事件中加入以下代码:<br>
<br>
AnsiString str1=Socket->ReceiveText();<br>
mmTalk->Lines->Add(str1);<br>
int i;<br>
for(i=0;i<ServerSocket1->Socket->ActiveConnections;i++)<br>
ServerSocket1->Socket->Connections[i]->SendText(str1);<br>
<br>
程序作为客户机的设置:<br>
当单击"连接"时,如果还未连接,则询问要连接的主机,然后连接之,屏蔽"监听";如果已经连接,则断开连接。"监听"使能。所以,在ckConnect的OnClick事件中加入以下代码:<br>
<br>
if(ClientSocket1->Active)<br>
{<br>
ClientSocket1->Active=false;<br>
ckConnect->Checked =false;<br>
}<br>
else<br>
{<br>
AnsiString Server="localhost";<br>
if(InputQuery("连接","请输入要连接的主机地址:",Server))<br>
{<br>
ClientSocket1->Host=Server;<br>
ClientSocket1->Active=true;<br>
ckConnect->Checked =true;<br>
}<br>
}<br>
ckListen->Enabled= !(ckConnect->Checked);<br>
<br>
当连接服务器成功时,在状态栏中显示此信息,所以,在ClientSocket1的ClientSocket1Connect中加入:<br>
<br>
StatusBar1->Panels->Items[0]->Text ="连接到主机:"+Socket->RemoteHost;<br>
当服务器发送字符串来时,把它加入mmTalk中,但如果本字符串就是自已发送的(因为服务器会把收到的消息发给每一客户),为条信息就是重复的,所以,要比较mmTalk中最后两条信息是否相同,如果相同,则删除重复信息。代码如下:<br>
<br>
mmTalk->Lines->Add(Socket->ReceiveText());<br>
int i=mmTalk->Lines->Count-1;<br>
if(mmTalk->Lines->Strings[i]==mmTalk->Lines->Strings[i-1])<br>
mmTalk->Lines->Delete(i);<br>
<br>
公用部分 <br>
当在edTalk输入交谈内容,按回车键表示输入完成,此时把交谈内容发送出去并清除edTalk的内容。在发送信息时,要看本程序是作为服务器还是客户机,如果是服务器则把信息发送到每一个客户;如果是作为客户则把信息发送到服务器。代码如下:<br>
<br>
if(Key==13)<br>
{<br>
mmTalk->Lines->Add(edName->Text+":"+edTalk->Text);<br>
if(ckListen->Enabled&&ckConnect->Enabled==false)<br>
//"监听"有效,"连接"无效。表示是服务器<br>
{<br>
int i;<br>
for(i=0;i<ServerSocket1->Socket->ActiveConnections;i++)<br>
ServerSocket1->Socket->Connections[i]->SendText(edName->Text+":"+edTalk->Text);<br>
}<br>
else<br>
{<br>
ClientSocket1->Socket->SendText(edName->Text+":"+edTalk->Text);<br>
}<br>
edTalk->Text="";<br>
}<br>
mmTalk的内容不可能永远增加,所以当它有100行时就清空它,在mmTalk的OnChange事件中检查:<br>
<br>
if(mmTalk->Lines->Count>=100)mmTalk->Lines->Clear();<br>
<br>
当然你也可以双击mmTalk来清空它,在mmTalk的OnDblClick事件中加入:<br>
<br>
mmTalk->Lines->Clear();<br>
当你觉得谈话的内容很有意思,你可以单击bbtSave打开保存对话框设置保存特性,所以在bbtSave的onClick中加入代码:<br>
<br>
if(sdTalk->Execute())<br>
mmTalk->Lines->SaveToFile(sdTalk->FileName);<br>
<br>
OK,我们的闲聊程序就完成了,在局域网中试试吧?如果你只有一台机器,客户程序在连接时服务器时输入localhost或你机器的名字就可以了。<br>
<br>
熟悉了这两个组件我们就可以写如联众游戏一样的网络游戏了(至少理论上如此),我也正想写一个网上赌博程序去诈骗我的同事,千万不要告诉他们哦!:=)</p>
</td>
</tr>
</table>
</div>
</BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -