?? 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> 四)網(wǎng)上聊天程序的編制<BR><BR> 4.1
程序中服務器端所起的作用。
<BR><BR> 從圖示中可以看到服務器端的兩個winsock控件之間并不存在直接的通訊,同時sckServer1和sckClient2及sckServer2和sckClient1之間是不能直接通訊的。這也即是說若sckClient1向sckClient2發(fā)出信息,信息首先被sckServer1接受,sckServer1再將信息傳給程序的信息處理部分,信息處理部分再將處理好的信息傳給sckServer2,再由sckServer2傳給sckClient2。反之亦然。那么服務器端的信息處理部分又進行什么工作呢?<BR><BR> 1.
對通訊的通道數(shù)作一些限制。<BR><BR> 2. 對使用后已關閉的通道,必須能夠重新使用以節(jié)省資源。<BR><BR> 3.
必須對所傳遞的數(shù)據(jù)包信息作甑別,從而作出不同的處理。<BR><BR> 通過解開數(shù)據(jù)的包頭就可區(qū)分不同的信息。<BR><BR> 網(wǎng)上聊天有兩種方式:第一種,以廣播方式;第二種,以點對點的方式。廣播方式即所有客戶都能收到某一客戶發(fā)出的信息。點對點的方式即想說“悄悄話”的一對客戶專門開辟了一間談話的“小屋”,別的客戶不能“聽”到他們的談話。在下面的程序中將看到如何利用數(shù)據(jù)的不同包頭來區(qū)分用戶是想以廣播方式還是以點對點的方式進行談話的(點對點方式數(shù)據(jù)的包頭為“PT”,廣播方式則無包頭)。<BR><BR> 4.2
客戶端的程序<BR><BR> 1. 在客戶端創(chuàng)建一個新的工程將其命名為“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
"服務器未開或網(wǎng)絡出錯!"<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.
在服務器端創(chuàng)建一個新的工程將其命名為“ServerPrj”。<BR><BR> 2.
將缺省窗體命名為“frmServer”。<BR><BR> 3.
在窗體中添加一個ListBox控件,將其命名為“l(fā)stReceive”。<BR><BR> 4.
在窗體中添加三個WinSock控件,將其分別命名為“sckListen”,sckBusy和“sckServer”并將“sckServer”的“Index”屬性設置為0。<BR><BR> 5.
在窗體中添加如下代碼.。<BR><BR> '最大通道數(shù)<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屬性給所有連接在服務器上的客戶發(fā)消息<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> 從程序中可以看到:第一,程序中限制了通道數(shù)(10路)。第二,通過判斷WinSock控件的State屬性是否為0(關閉狀態(tài)),來重新使用已關閉的WinSock控件。第三,通過給WinSock控件傳遞的信息加上包頭,來對信息進行不同的處理(程序中若信息前加上了“PT"(Private
Talk)+"通道數(shù)”的包頭,由此就知道客戶想要同擁有此“通道數(shù)”的另一客戶進行“悄悄話”,否則就以廣播方式將信息發(fā)給所有客戶)。<BR><BR><BR> 五)
結(jié)束語<BR><BR> WinSock控件不僅僅是用來編制網(wǎng)上聊天程序,而且可以用來編制各種網(wǎng)絡游戲或網(wǎng)絡通信程序。實際上WinSock控件是編制各種C/S程序的利器。在實際使用中通常是將WinSock控件封裝在Activex
DLL(進程內(nèi))、Activex EXE(進程外)部件的類中(類中引用)來使用的。通過區(qū)分所傳信息前的不同的包頭,用RaiseEvent命令引發(fā)不同
的事件,再對事件分別進行處理。這樣不僅增加了程序的可調(diào)試性和安全性,而且更符合事件驅(qū)動編程方法的特點。 </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>版權(quán)所有©1999 太平洋電腦信息網(wǎng)<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 + -