📄 vb20.htm
字号:
<TD align=middle width=24><SMALL>0</SMALL></TD>
<TD width=152><SMALL>缺省的。关闭</SMALL></TD></TR>
<TR>
<TD width=160><SMALL>sckopen</SMALL></TD>
<TD align=middle width=24><SMALL>1</SMALL></TD>
<TD width=152><SMALL>打开</SMALL></TD></TR>
<TR>
<TD width=160><SMALL>scklistening</SMALL></TD>
<TD align=middle width=24><SMALL>2</SMALL></TD>
<TD width=152><SMALL>侦听</SMALL></TD></TR>
<TR>
<TD width=160><SMALL>sckconnectionpending</SMALL></TD>
<TD align=middle width=24><SMALL>3</SMALL></TD>
<TD width=152><SMALL>连接挂起</SMALL></TD></TR>
<TR>
<TD width=160><SMALL>sckresolvinghost</SMALL></TD>
<TD align=middle width=24><SMALL>4</SMALL></TD>
<TD width=152><SMALL>识别主机</SMALL></TD></TR>
<TR>
<TD width=160><SMALL>sckhostresolved</SMALL></TD>
<TD align=middle width=24><SMALL>5</SMALL></TD>
<TD width=152><SMALL>已识别主机</SMALL></TD></TR>
<TR>
<TD width=160><SMALL>sckconnecting</SMALL></TD>
<TD align=middle width=24><SMALL>6</SMALL></TD>
<TD width=152><SMALL>正在连接</SMALL></TD></TR>
<TR>
<TD width=160><SMALL>sckconnected</SMALL></TD>
<TD align=middle width=24><SMALL>7</SMALL></TD>
<TD width=152><SMALL>已连接</SMALL></TD></TR>
<TR>
<TD width=160><SMALL>sckclosing</SMALL></TD>
<TD align=middle width=24><SMALL>8</SMALL></TD>
<TD width=152><SMALL>同级人员正在关闭连接</SMALL></TD></TR>
<TR>
<TD width=160><SMALL>sckerror</SMALL></TD>
<TD align=middle width=24><SMALL>9</SMALL></TD>
<TD width=152><SMALL>错误</SMALL></TD></TR></TBODY></TABLE>
<P><BR> 下面主要要用到sckClosed.sckConnected两个State属性的值。<BR><BR> 四)网上聊天程序的编制<BR><BR> 4.1
程序中服务器端所起的作用。
<BR><BR> 从图示中可以看到服务器端的两个winsock控件之间并不存在直接的通讯,同时sckServer1和sckClient2及sckServer2和sckClient1之间是不能直接通讯的。这也即是说若sckClient1向sckClient2发出信息,信息首先被sckServer1接受,sckServer1再将信息传给程序的信息处理部分,信息处理部分再将处理好的信息传给sckServer2,再由sckServer2传给sckClient2。反之亦然。那么服务器端的信息处理部分又进行什么工作呢?<BR><BR> 1.
对通讯的通道数作一些限制。<BR><BR> 2. 对使用后已关闭的通道,必须能够重新使用以节省资源。<BR><BR> 3.
必须对所传递的数据包信息作甑别,从而作出不同的处理。<BR><BR> 通过解开数据的包头就可区分不同的信息。<BR><BR> 网上聊天有两种方式:第一种,以广播方式;第二种,以点对点的方式。广播方式即所有客户都能收到某一客户发出的信息。点对点的方式即想说“悄悄话”的一对客户专门开辟了一间谈话的“小屋”,别的客户不能“听”到他们的谈话。在下面的程序中将看到如何利用数据的不同包头来区分用户是想以广播方式还是以点对点的方式进行谈话的(点对点方式数据的包头为“PT”,广播方式则无包头)。<BR><BR> 4.2
客户端的程序<BR><BR> 1. 在客户端创建一个新的工程将其命名为“ClientPrj”<BR><BR> 2. 将缺省窗体命名为
frmClient。<BR><BR> 3. 将窗体的标题改为“Client”。<BR><BR> 4. 在窗体中添加一个 WinSock
控件,并将其命名为 tcpClient。<BR><BR> 5. 在 frmClient 中添加一个ListBox
控件。将其命名为lstReceive。<BR><BR> 6. 在 frmClient 中添加一个 TextBox 控件。将其命名为
txtSend。<BR><BR> 7. 在窗体上放两个 CommandButton 控件,并将其命名为
cmdConnect和cmdSent。<BR><BR> 8. 将cmdConnect控件的标题改为 Connect,
将cmdSent控件的标题改为 Sent。<BR><BR> 9. 在窗体中添加如下的代码。<BR><BR> Private Sub
cmdConnect_Click()<BR><BR> On Error GoTo ErrorPro<BR><BR>
sckClient.Connect<BR><BR> Exit Sub<BR><BR> ErrorPro:<BR><BR> MsgBox
"服务器未开或网络出错!"<BR><BR> End<BR><BR> End Sub<BR><BR> Private Sub
cmdSent_Click()<BR><BR> sckClient.SendData txtSent.Text<BR><BR> End
Sub<BR><BR> Private Sub Form_Load()<BR><BR> '
RemoteComputerName为服务器端的计算机名或IP地址。<BR><BR> sckClient.RemoteHost =
"RemoteComputerName"<BR><BR> sckClient.RemotePort = 1000<BR><BR> End
Sub<BR><BR><BR><BR> Private Sub sckClient_Close()<BR><BR> MsgBox
"服务器通道已关闭!"<BR><BR> End<BR><BR> End Sub<BR><BR><BR><BR> Private Sub
sckClient_Connect()<BR><BR> MsgBox "连接成功!"<BR><BR> cmdConnect.Enabled =
False<BR><BR> End Sub<BR><BR><BR><BR> Private Sub
sckClient_DataArrival(ByVal bytesTotal As Long)<BR><BR> Dim s As
String<BR><BR> sckClient.GetData s<BR><BR> lstReceive.AddItem
s<BR><BR> End Sub<BR><BR><BR><BR> Private Sub sckClient_Error(ByVal
Number As Integer, Description As String, ByVal Scode As Long, _ ByVal
Source As String, ByVal HelpFile As String, ByVal HelpContext As Long,
CancelDisplay As
Boolean)<BR><BR> sckClient.Close<BR><BR> cmdConnect.Enabled =
True<BR><BR> End Sub<BR><BR> 4.3 服务器端的程序<BR><BR> 1.
在服务器端创建一个新的工程将其命名为“ServerPrj”。<BR><BR> 2.
将缺省窗体命名为“frmServer”。<BR><BR> 3.
在窗体中添加一个ListBox控件,将其命名为“lstReceive”。<BR><BR> 4.
在窗体中添加三个WinSock控件,将其分别命名为“sckListen”,sckBusy和“sckServer”并将“sckServer”的“Index”属性设置为0。<BR><BR> 5.
在窗体中添加如下代码.。<BR><BR> '最大通道数<BR><BR> Private MaxChan As
Integer<BR><BR> <BR><BR> Private Sub Form_Load()<BR><BR> Dim i As
Integer<BR><BR> MaxChan = 10<BR><BR> For i = 1 To MaxChan - 1<BR><BR>
Load sckServer(i)<BR><BR> Next i<BR><BR> sckListen.LocalPort =
1000<BR><BR> sckListen.Listen<BR><BR> End Sub<BR><BR><BR><BR> Private
Sub sckBusy_Close()<BR><BR> sckBusy.Close<BR><BR> End
Sub<BR><BR><BR><BR> Private Sub sckBusy_DataArrival(ByVal bytesTotal As
Long)<BR><BR> sckBusy.SendData
"服务器忙,请稍后再连接!"<BR><BR> DoEvents<BR><BR> End Sub<BR><BR><BR><BR> Private
Sub sckListen_ConnectionRequest(ByVal requestID As Long)<BR><BR> Dim i As
Integer<BR><BR> '决定由哪一Winsock接受请求<BR><BR> For i = 0 To MaxChan -
1<BR><BR> If sckServer(i).State = 0 Then<BR><BR> Exit For<BR><BR>
End If<BR><BR> Next i<BR><BR> If sckServer(i).State = 0 Then<BR><BR>
sckServer(i).Accept requestID<BR><BR> Exit Sub<BR><BR> End
If<BR><BR> '如果所有Winsock都用完则由专门的“忙”Winsock接受请求,以免用户要求得不到响应<BR><BR> sckBusy.Close<BR><BR> sckBusy.Accept
requestID<BR><BR> End Sub<BR><BR><BR><BR> Private Sub
sckListen_Error(ByVal Number As Integer, Description As String, ByVal
Scode As Long, _ ByVal Source As String, ByVal HelpFile As String, ByVal
HelpContext As Long, CancelDisplay As
Boolean)<BR><BR> sckListen.Close<BR><BR> sckListen.LocalPort =
1000<BR><BR> sckListen.Listen<BR><BR> End Sub<BR><BR><BR><BR> Private
Sub sckServer_Close(Index As
Integer)<BR><BR> sckServer(Index).Close<BR><BR> End
Sub<BR><BR><BR><BR> Private Sub sckServer_DataArrival(Index As Integer,
ByVal bytesTotal As Long)<BR><BR> Dim s As String<BR><BR> Dim i As
Integer<BR><BR> sckServer(Index).GetData s<BR><BR> If
UCase(Left(Trim(s), 2)) = "PT" Then '判断是否为悄悄话,点对点方式<BR><BR> If
IsNumeric(Mid(Trim(s), 3, 1)) Then<BR><BR> i = Mid(Trim(s), 3,
1)<BR><BR> sckServer(i).SendData "Channel " & Index & " " &
Right(Trim(s), Len(Trim(s)) - 3)<BR><BR> DoEvents<BR><BR> End
If<BR><BR> Else '广播方式<BR><BR> For i = 0 To MaxChan - 1<BR><BR>
'利用winsock的State属性给所有连接在服务器上的客户发消息<BR><BR> If sckServer(i).State = 7
Then<BR><BR> sckServer(i).SendData "Channel " & Index & " "
& Trim(s)<BR><BR> DoEvents<BR><BR> End If<BR><BR> Next
i<BR><BR> End If<BR><BR> lstReceive.AddItem "Channel " & Index &
" " & Trim(s)<BR><BR> End Sub<BR><BR><BR><BR> Private Sub
sckServer_Error(Index As Integer, ByVal Number As Integer, Description As
String, _<BR><BR> ByVal Scode As Long, ByVal Source As String, ByVal
HelpFile As String, ByVal HelpContext As _<BR><BR> Long, CancelDisplay As
Boolean)<BR><BR> sckServer(Index).Close<BR><BR> End
Sub<BR><BR> 从程序中可以看到:第一,程序中限制了通道数(10路)。第二,通过判断WinSock控件的State属性是否为0(关闭状态),来重新使用已关闭的WinSock控件。第三,通过给WinSock控件传递的信息加上包头,来对信息进行不同的处理(程序中若信息前加上了“PT"(Private
Talk)+"通道数”的包头,由此就知道客户想要同拥有此“通道数”的另一客户进行“悄悄话”,否则就以广播方式将信息发给所有客户)。<BR><BR><BR> 五)
结束语<BR><BR> WinSock控件不仅仅是用来编制网上聊天程序,而且可以用来编制各种网络游戏或网络通信程序。实际上WinSock控件是编制各种C/S程序的利器。在实际使用中通常是将WinSock控件封装在Activex
DLL(进程内)、Activex EXE(进程外)部件的类中(类中引用)来使用的。通过区分所传信息前的不同的包头,用RaiseEvent命令引发不同
的事件,再对事件分别进行处理。这样不仅增加了程序的可调试性和安全性,而且更符合事件驱动编程方法的特点。 </P>
<P align=right><A
href="http://www.pconline.com.cn/experience/subject/VB/index.html">----更多的文章</A></P><!-- #EndEditable --></TD></TR></TBODY></TABLE>
<TABLE align=center border=0 cellPadding=0 cellSpacing=0 width=760>
<TBODY>
<TR>
<TD bgColor=#666666 width=1><IMG height=1 src="vb20.files/blank.gif"
width=1></TD>
<TD align=right vAlign=bottom width=170><IMG height=10
src="vb20.files/blank.gif" width=170><BR></TD>
<TD bgColor=#666666 width=1><IMG height=1 src="vb20.files/blank.gif"
width=1></TD>
<TD width=21><IMG height=1 src="vb20.files/blank.gif" width=21></TD>
<TD bgColor=#eeeeee width=566><IMG height=10 src="vb20.files/blank.gif"
width=566><BR>版权所有©1999 太平洋电脑信息网<BR><FONT
face="Arial, Helvetica, sans-serif"><A
href="mailto:exp@pconline.com.cn">exp@pconline.com.cn</A></FONT> <IMG
height=1 src="vb20.files/hhvisit.html" width=1> </TD></TR></TBODY></TABLE><!-- #EndTemplate --></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -