《VB中使用WinSock控件编写网络程序-.pdf》由会员分享,可在线阅读,更多相关《VB中使用WinSock控件编写网络程序-.pdf(19页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、VB 中使用 WinSock控件编写网络程序WinSock 控件能够通过UDP 协议(用户数据报协议)或TCP 协议(数据传输协议)连接到远程的机器并进行数据交换。这两种协议都能用来创建客户端和服务端应用程序。就像定时器控件一样,WinSock 控件运行时没有一个可视的界面。可能的用途创建客户端应用程序,它能在信息到达中央服务器之前把用户的信息收集起来。创建服务端应用程序,它能作为来自多个用户的数据一个集中处理点。创建“聊天”程序。协议的选择当我们使用WinSock 控件时,首先要确定的是使用TCP 还是 UDP 协议。它们之间主要的区别在于连接状态:TCP 协议控件是一个基于连接的协议,就像
2、电话机一样,用户必须在通话之前建立连接;UDP 是一个无连接的协议,两台计算机之间的事务处理就像传纸条一样:一台计算机向另一台计算机发送消息,但是它们之间并没有一个明确的连接路径。另外,发送的单个信息量的大小取决于网络。通常,你要创建的应用程序的类别就决定了你要选择的协议。以下是几个能够帮助你选择合适的协议的问题:当发送或接收数据时,该应用程序需要从服务端或客户端获得认证吗?如果要的话,那么 TCP 协议就正好需要在发送或接受数据前建立明确的连接。要发送的数据量大吗?(就像图片、声音文件之类)一旦建立了连接,TCP 协议就会保持连接并保证数据的完整性。但是,这种连接会占用的更多的处理器资源,成
3、本也会更高一些。数据是陆续传输的,还是一次全部传完呢?比如,如果你要创建的应用程序在某些任务完成时会告知具体的计算机,那么选择UDP 协议会更合适一些。UDP 协议也更适合于发送小量数据。协议的配置配置你的应用程序所用到的协议:在设计阶段,单击工具窗口里的协议,选择sckTCPProtocol或 sckUDPProtocol。你也可以在代码里配置协议,就像下面这样:Winsock1.Protocol=sckTCPProtocol 确定你的计算机名要连接到远程的计算机,你必须知道它的IP 地址或别名。IP 地址是一串用句点分隔的3 位数字。通常,计算机的别名更容易让人记住。按下面的步骤可以找到你
4、的计算机名:在“任务栏”里单击“开始”在“设置”选项里单击“控制面板”;双击“网络”图标;单击“网络标识”在“计算机名”中显示的就是你的计算机名。一旦你找到你的计算名,它就可以作为远程主机的属性来用了。TCP 连接入门当用 TCP 控件创建应用程序的时候,必须首先明确你的程序是作为服务端还是客户端。创建服务端程序就意味着你的程序能够在指定的端口进行“监听”,而客户端则能够提出请求,服务端能够接受请求并实现连接。一旦连接建立起来,客户端和服务端就能够自由地进行通信。创建服务端程序下面是创建一个简单服务端程序的步骤:创建一个标准EXE 工程;把默认窗体(Default form)的名字改为frmS
5、erver;把 form 的标题(caption)改为 TCP Server;把 Winsock控件拉到窗体中,并命名为tcpServer;在窗体中添加2 个文本框,分别命名为txtSendData和 txtOutput,在窗体中加入下列代码;Private Sub Form_Load()Set the LocalPort property to an integer.Then invoke the Listen method.tcpServer.LocalPort=1001 tcpServer.Listen frmClient.Show Show the client form.End Su
6、b Private Sub tcpServer_ConnectionRequest _(ByVal requestID As Long)Check if the controls State is closed.If not,close the connection before accepting the new connection.If tcpServer.State sckClosed Then _ tcpServer.Close Accept the request with the requestID parameter.tcpServer.Accept requestID End
7、 Sub Private Sub txtSendData_Change()The TextBox control named txtSendData contains the data to be sent.Whenever the user types into the textbox,the string is sent using the SendData method.tcpServer.SendData txtSendData.Text End Sub Private Sub tcpServer_DataArrival _(ByVal bytesTotal As Long)Decla
8、re a variable for the incoming data.Invoke the GetData method and set the Text property of a TextBox named txtOutput to the data.Dim strData As String tcpServer.GetData strData txtOutput.Text=strData End Sub 上面就是创建一个简单的服务端应用程序的过程。然而,要完成整个过程,你还得创建一个客户端程序。创建 TCP 客户端程序在工程中添加一个新的窗体(form),并命名为frmClient;将
9、窗体的标题(caption)改为 TCP Client;添加一个 Windsock控件到窗体中,命名为tcpCllient;添加 2 个文本框控件到frmClient窗体,分别命名为txtSend 和 txtOutput;添加一个按钮控件(CommandButton)到窗体,命名为cmdConnecti;将按钮控件标题(caption)改为 Connect;在窗体中添加下面代码:注:确保将远程主机属性(RemoteHost property)改为你的计算机别名。Private Sub Form_Load()The name of the Winsock control is tcpClient
10、.Note:to specify a remote host,you can use either the IP address(ex:121.111.1.1)or the computers friendly name,as shown here.tcpClient.RemoteHost=RemoteComputerName tcpClient.RemotePort=1001 End Sub Private Sub cmdConnect_Click()Invoke the Connect method to initiate a connection.tcpClient.Connect En
11、d Sub Private Sub txtSendData_Change()tcpClient.SendData txtSend.Text End Sub Private Sub tcpClient_DataArrival _(ByVal bytesTotal As Long)Dim strData As String tcpClient.GetData strData txtOutput.Text=strData End Sub 以上代码就能创建一个简单的客/服应用程序。要试着让两者建立连接,可以运行工程,单击 Connect。在任意一个txtSendData文本框中输入文本,同样的文本信息
12、就会出现在另一个窗体的txtOutput文本框中出现。接受多个连接请求上面介绍的服务端程序智能接受一个连接请求。但是,通过创建一组控件,并使用同样的控件来接受多个连接请求也是可能的。在这种情况下,你不需要关闭连接,只要创建新的控件实例(通过配置它的索引属性),调用新的实例中的接受方法。下面的代码中,假定在一个叫sckServer的窗体中有一个Winsock控件,它的索引属性设置为0。这样这个控件就是控件数组的一部分。在声明段中,生命一个模块级变量intMax。在窗体的载入事件中,intMax 被设置为 0,数组中第一个控件的本地端口属性被设置为 1001。监听方法在控件中被调用,它被作为“监听
13、控件”。每个连接请求到来时,代码会测试看它的索引(Index)是否为 0(监听控件的值),如果是0,监听控件中intMax 值增 1,并用这个值创建新的控件实例。新的控件实例被用来接受连接请求。Private intMax As Long Private Sub Form_Load()intMax=0 sckServer(0).LocalPort=1001 sckServer(0).Listen End Sub Private Sub sckServer_ConnectionRequest _(Index As Integer,ByVal requestID As Long)If Index=
14、0 Then intMax=intMax+1 Load sckServer(intMax)sckServer(intMax).LocalPort=0 sckServer(intMax).Accept requestID Load txtData(intMax)End If End Sub UDP 连接入门创建一个 UDP 应用程序比创建TCP 程序更简单,因为 UDP 协议不需要一个确定的连接。在上面的TCP 应用程序中,其中一个Winsock 控件必须明确的被设置为“监听”,而另一个必须用连接方法发起连接。相反,UDP 协议不需要明确的连接。要在2 个控件之间传送数据,(连接的双方)必须完成
15、三个步骤:确定远程主机属性为对方的计算机名;确定远程主机属性为第二个控件的本地端口属性;调用约定方法指定要被使用的本地端口。(下面将详细讨论该方法)创建一个的UDP 连接端创建一个标准EXE 工程;将默认窗体命名为frmPeerA;在窗体中添加一个Winsock控件,命名为udpPeerA;在属性(Properties)页,单击协议(Protocol),改为 UDPProtocol;添加 2 个文本框控件窗体中,分别命名为txtSend 和 txtOutput;在窗体中添加下面代码:Private Sub Form_Load()The controls name is udpPeerA Wit
16、h udpPeerA IMPORTANT:be sure to change the RemoteHost value to the name of your computer.RemoteHost=PeerB.RemotePort=1001 Port to connect to.Bind 1002 Bind to the local port.End With frmPeerB.Show Show the second form.End Sub Private Sub txtSend_Change()Send text as soon as its typed.udpPeerA.SendDa
17、ta txtSend.Text End Sub Private Sub udpPeerA_DataArrival _(ByVal bytesTotal As Long)Dim strData As String udpPeerA.GetData strData txtOutput.Text=strData End Sub 创建第二个UDP 连接端添加标准窗体到工程中;将窗体名改为frmPeerB;将窗体标题改为Peer B;在窗体中添加一个Windsock 控件并命名为udpPeerB;在属性页中单击Protocol,改为 UDPProtocol;添加 2 个文本框到窗体中,分别命名为txtS
18、end 和 txtOutput;在窗体中添加下面代码:Private Sub Form_Load()The controls name is udpPeerB.With udpPeerB IMPORTANT:be sure to change the RemoteHost value to the name of your computer.RemoteHost=PeerA.RemotePort=1002 Port to connect to.Bind 1001 Bind to the local port.End With End Sub Private Sub txtSend_Change
19、()Send text as soon as its typed.udpPeerB.SendData txtSend.Text End Sub Private Sub udpPeerB_DataArrival _(ByVal bytesTotal As Long)Dim strData As String udpPeerB.GetData strData txtOutput.Text=strData End Sub 关于约定方法上面代码中所涉及的,在创建UDP 应用程序时必须调用约定方法。这个约定的方法保留了控件用到的本地端口。例如,当你绑定控件到端口1001 时,其他的应用程序都不能用该端口
20、监听。当你希望阻止其他的应用程序使用某端口的时候,这个就很有用。这个约定方法也引起了争议。如果机器里有多个网络适配器,本地IP 允许你指定用哪个适配器。如果你忽略了这个争议性问题,控件就会使用计算机控制面板设置中,在网络控制面板对话框里列出的第一个网络适配器。在使用 UDP 协议时,你可以自由的切换远程主机和远程端口属性,同时保留本地端口范围。但是在使用UDP 协议时,你必须在改变远程主机和远程端口属性时关闭连接。共 4 页。-VB6.0 开发网络应用的5 个技巧Visual Basic 6.0(以下简称VB 6)以其强大的功能为广大软件开发人员所喜爱,被用来开发各种应用程序。随着Intern
21、et 的迅猛发展,VB 6 在网络方面的应用开发也越来越多。本文介绍笔者在实际编程开发中总结的5 个技巧,希望能为进行网络开发的朋友们提供一点参考。连通检测许多应用程序常常需要在程序中直接进行联网操作,以便进行一些必要的处理(如在线注册和在线帮助等),这就要求我们在程序中建立某些连接。很多软件在不知用户是否联网的情况下就启动浏览器查找网址,结果只能查出一错误网页,既浪费用户时间又没有任何效果。如果应用程序在查找网页之前能自动判断用户是否已经联网,就会节约许多时间,提高程序运行效率。下面是实现网络连通检测的VB 6 代码:Private Sub Form_Load()If IsConnected
22、=TRUE Then MsgBox(“您已经连通了Internet!”)End If If IsConnected=FALSE Then MsgBox(“您还没有连通Internet!”)End If End Sub Option Explicit/*有关的 API 声明和定义*/Public Declare Function RasEnumConnections Lib“RasApi32.dll”Alias“RasEnumConnectionsA”(lpRasCon As Any,lpcb As Long,lpcConnections As Long)As Long Public Decla
23、re Function RasGetConnectStatus Lib“RasApi32.dll”Alias“RasGetConnectStatusA”(ByVal hRasCon As Long,lpStatus As Any)As Long/*常数和变量的设定*/Public Const RAS95_MaxEntryName=256 Public Const RAS95_MaxDeviceType=16 Public Const RAS95_MaxDeviceName=32 Public Type RASCONN95 dwSize As Long hRasCon As Long szEnt
24、ryName(RAS95_MaxEntryName)As Byte szDeviceType(RAS95_MaxDeviceType)As Byte szDeviceName(RAS95_MaxDeviceName)As Byte End Type Public Type RASCONNSTATUS95 dwSize As Long RasConnState As Long dwError As Long szDeviceType(RAS95_MaxDeviceType)As Byte szDeviceName(RAS95_MaxDeviceName)As Byte End Type/*函数
25、IsConnected返回连通的状态,如果为True 则表示已连通*/Public Function IsConnected()As Boolean Dim TRasCon(255)As RASCONN95 Dim lg As Long Dim lpcon As Long Dim RetVal As Long Dim Tstatus As RASCONNSTATUS95 TRasCon(0).dwSize=412 lg=256*TRasCon(0).dwSize RetVal=RasEnumConnections(TRasCon(0),lg,lpcon)If RetVal 0 Then Msg
26、Box“错误”Exit Function End If Tstatus.dwSize=160 RetVal=RasGetConnectStatus(TRasCon(0).hRasCon,Tstatus)If Tstatus.RasConnState=H2000 Then IsConnected=TRUE Else IsConnected=FALSE End If End Function 启动拨号网络中的连接由于拨号网络不是一个可执行文件,所以要启动拨号网络,需要借助explorer.exe。但若是要启动拨号网络中的某一个连接,则要借助rundll.exe 和 rnaui.dll 两个文件。启
27、动方法如下(假定此连接名称为163):Shell“rundll rnaui.dll,RnaDial 163”,vbNormalFocus 上面假定了连接名称,但在实际编程中我们是不知道连接名称的。在窗体上放置一个命令按钮(cmdCallConnect),在其单击事件中进行连接处理。下面的代码介绍如何取得默认的连接名称并启动它:Option Explicit/*有关的 API 声明*/Private Declare Function RegOpenKeyEx Lib“advapi32”Alias“RegOpenKeyExA”(ByVal hKey As Long,ByVal lpSubKey A
28、s String,ByVal ulOptions As Long,ByVal samDesired As Long,phkResult As Long)As Long Private Declare Function RegQueryvalueEx Lib“advapi32”Alias“RegQueryvalueExA”(ByVal hKey As Long,ByVal lpvalueName As String,ByVal lpReserved As Long,ByRef lpType As Long,ByVal szData As String,ByRef lpcbData As Long
29、)As Long Private Declare Function RegCloseKey Lib“advapi32”(ByVal hKey As Long)As Long/*常数的设定*/Const HKEY_CURRENT_USER=H80000001 Const ERROR_SUCCESS=0 在命令按钮(cmdCallConnect)中加入如下代码:Private Sub cmdCallConnect_Click()/*启动默认拨号连接*/Shell“rundll rnaui.dll,RnaDial”GetConnect,vbNormalFocus End Sub/*取得连接的函数(G
30、etConnect)*/Public Function GetConnect()As String Dim hKey As Long Dim SubKey As String/*主键*/hKey=HKEY_CURRENT_USER/*子键*/SubKey=“RemoteAccess”/*取得默认连接名*/GetConnect=GetRegvalue(hKey,SubKey,“Default”)End Function/*取得注册的函数(GetRegvalue)*/Public Function GetRegvalue(hKey As Long,lpszSubKey As String,szKe
31、y As String)As Variant On Error GoTo ErrorRoutineErr:Dim phkResult As Long Dim lResult As Long Dim szBuffer As String Dim lBuffSize As Long/*创建缓冲区*/szBuffer=Space(255)lBuffSize=Len(szBuffer)/*打开注册键*/RegOpenKeyEx hKey,lpszSubKey,0,1,phkResult/*取得查询结果*/lResult=RegQueryvalueEx(phkResult,szKey,0,0,szBuf
32、fer,lBuffSize)/*关闭注册键*/RegCloseKey phkResult/*返回结果*/If lResult=ERROR_SUCCESS Then GetRegvalue=Left(szBuffer,lBuffSize 1)Else GetRegvalue=“”End If Exit Function/*意外处理*/ErrorRoutineErr:GetR egvalue=“”End Function 设计 E-mail 的接收部分在 VB 6 菜单上点击“工程/部件.”,弹出“部件”对话框,在对话框的控件卡中选中Microsoft MAPI Controls 6.0控件,点击
33、“确定”按钮后,工具箱上增加了MAPIMessage和MAPISession两个图标。在 Form 上加入一个MAPIMessage控件,取名为MAPIMessage1;再加入一个MAPISession控件,取名为 MAPISession1;再加入三个TextBox 控件,分别取名为Subject、Content 和 Indexno,将它们的Caption 分别改为邮件标题、邮件内容和邮件索引号;在TextBox 前各加入一个Label 控件,将Caption 分别改为标题、内容和索引号。将 MAPIMessage1的各项属性设置如下:DownLoadMail=TRUE;LogonUI=TRU
34、E;NewSession=FALSE;UserName=“接收 E mail”。在 Form 上加入一个按钮(Getmail),将其Caption 改为取邮件。在 Getmail_Click()事件中加入以下程序代码,程序的功能是使我们接收E mail。MAPIMessage1.Fetch Form1.Caption=MAPIMessage1.MsgCount MAPIMessage1.MsgIndex=CINT(Indexno.text)Subject.Text=MAPIMessage1.MsgNoteText Content.Text=MAPIMessage1.MsgSubject 其中
35、Fetch 命令用来将信件抓到系统存储器的inbuffer 中。我们将信件抓回来后,可以通过 MsgCount属性知道信件数量,接着可以用MsgIndex 设置要看哪一封信件的内容、标题等。设计 E-mail 的发送部分1参数设置进入 Exchange系统,选择新增设置文件后屏幕上会显示所需要的信息服务,选择Internet Mail。把设置文件的名称设为test。屏幕会显示两个选项,您可以选择以Modem 方式或以Network 方式连接。笔者所用的是Modem 方式;假若您是使Internet 专线,就要选择Network 方式。选择 Modem 方式后,Exchange会要求我们输入邮件
36、服务器的IP 地址。接着将Transform Message的模式设置为Automatic,这样当我们连接到邮件服务器时,新的信息会自动下载到本地端。接下来,将您所使用的E mail 地址、全名、口令和下载路径等一一设置好。2程序设计在 Form 上加入一个MAPIMessage控件,取名为MAPIMessage1;加入一个MAPISession控件,取名为MAPISession1;并加入三个TextBox 控件,取名为Subject、Content 和 Addr。并在三个 TextBox 前各加入一个Label,将 Caption 分别改为标题、内容和地址。将 MAPIMessage1的各项
37、属性设置如下:DownLoadMail=TRUE;LogonUI=TRUE;NewSession=FALSE;UserName=“发送 E mail”。这里将 DownLoadMail设置为 TRUE,当程序和邮件服务器第一次连接时,会将新的邮件下载到本地端。将LogonUI设置为 TRUE,则当您程序中Logon 名称输入错误时,系统会显示一个Message Box来让您输入正确的名称。由于这个程序仅使用一个Session,所以可将NewSession设置成 FALSE。如果您有许多 Session 要建立的话,则将它设置成TRUE。UserName中所填的,是我们在Exchange中所新增
38、的设置文件名称,如果没有填内容的话,系统将会显示一些Message Box请您输入文件。在 Form 上加入三个按钮,Logon、Logoff 和 Send,并分别将它们的Caption 改为登录、离网和发送。在 Logon_Click()事件中加入以下程序代码,程序的功能是使我们登录到邮件服务器:MAPISession1.SignOn MAPIMessage1.SessionID=MAPISession1.SessionID sgBox“Your ID is”Str(MAPISession1.SessionID)其中 MAPISession1.SignOn是作登录的动作。在登录时,因为已经将
39、MAPIMessage1控件的 DownLoadMail属性设置为TRUE,所以可以在屏幕上看到Message Box,显示系统正在下载邮件。登录成功后,系统会传回一个SessionID,将该 ID 填入 MAPIMessage1的 SessionID中,这样就可以利用该Session 来传送 E mail,同时用Message Box通知用户发送成功。在 Logoff_Click()事件中加入以下程序代码,程序的功能是使我们离开邮件服务器:MAPIS1.SignOff 在 Send_Click()事件中加入以下程序代码,程序的功能是使我们发送E mail:MAPIMessage1.Compo
40、se MAPIMessage1.RecipDisplayName=Addr.text MAPIMessage1.AddressResolveUI=TRUE MAPIMessage1.MsgSubject=Subject.text MAPIMessage1.MsgNoteText=Content.text MAPIMessage1.Send MsgBox“您发送成功啦!”其中 Compose命令的主要目的是使您可以改变RecipDisplayName的内容,将所需传送的 E mail 地址、主题和文章内容分别填入RecipDisplayName、MsgSubject和MsgNoteText,接着
41、用Send 命令发送出去b访问 Internet 并调用 Explorer 1实现方法和控件介绍首先在 VB 6 菜单上点击“工程/部件.”,弹出“部件”对话框,在对话框的控件卡中选中Microsoft Internet Controls控件,点击“确定”按钮后工具箱上增加一个WebBrowser图标,将它加到 Form 中。该控件有以下几个重要的方法和事件:GoHome:装入 IE 设定的起始页;Navigate:装入页面,如Object.Navigate url,其中 url 为 URL 地址,如http:/;GoBack:返回上一个页面;GoForward:进入下一个页面;Stop:停止
42、载入页面;BeforeNavigate Event:在每次装入页面前调用该事件;StatusTextChange Event:每次浏览器的操作状态改变时调用该事件。2具体的访问方法将 WebBrowser图标添加到Form 中。并在 Form 上添加 4 个命令按钮,Name 属性分别为:GoButton、BackButton、ForwardButton和 StopButton,通过这4 个命令按钮可以实现对浏览器的操作。在 Form 上添加一个TextBox 控件,用来输入和显示当前的页面地址。在 Form 上添加一个Label 控件,用来显示当前浏览器操作状态。/*载入 Form*/Pri
43、vate Sub Form_Load()/*程序装入后进入IE 设定的起始页*/WebBrowser1.GoHome End Sub/*改变 Form 尺寸*/Private Sub Form_Resize()/*改变窗口大小后同时改变控件的大小*/WebBrowser1.Width=Form1.ScaleWidth WebBrowser1.Height=Form1.ScaleHeight 900 Label1.Width=Form1.ScaleWidth Label1.Top=Form1.ScaleHeight 300 End Sub Private Sub BackButton_Click
44、()/*返回上一个页面*/WebBrowser1.GoBack End Sub Private Sub ForwardButton_Click()/*进入下一个页面*/WebBrowser1.GoForward End Sub Private Sub GoButton_Click()/*浏览输入的页面*/WebBrowser1.Navigate(Text1.Text)End Sub Private Sub StopButton_Click()/*停止浏览*/WebBrowser1.Stop End Sub Private Sub Text1_KeyPress(KeyAscii As Integ
45、er)/*输入地址后进行浏览*/If KeyAscii=13 Then WebBrowser1.Navigate(Text1.Text)End If End Sub Private Sub WebBrowser1_BeforeNavigate(ByVal URL As String,ByVal Flags As Long,ByVal TargetFrameName As String,PostData As Variant,ByVal Headers As String,Cancel As Boolean)/*将当前显示的页面的URL 地址显示在Text1 上*/Text1.Text=URL
46、End Sub Private Sub WebBrowser1_StatusTextChange(ByVal Text As String)/*Label1 显示当前页面装入情况*/Label1.Caption=Text End Sub-VB6 实现局域网多站点互连完全手册随着时代的发展,我们已经步入了信息化时代,网络的普及和应用,使得越来越多的编程人员加入网络软件开发的行列。不过现在对于比较完整的介绍在局域网中多个站点互连的文章,笔者还未见到,这篇文章较完整的介绍了如何利用Visual Basic 6的 Winsock控件实现局域网中多个站点在客户机/服务器模式下的互连,并给出了几种连接方案
47、进行比较,对于 Winsock编程过程中遇到的一些问题做了解答。这里对 Winsock控件的属性、方法和事件的介绍限于篇幅就不介绍了,下面以最简单的 C/S 模式下一台服务器和一台客户机的连接来说明其整个连接过程。用框图表示如图1 所示。首先运行服务器端的程序,使TcpServer处于监听状态,然后运行客户机端的程序,单击【连接服务器】按钮后,客户机端调用Connect方法呼叫服务器(根据 RemoteHostIP远程计算机IP 地址和 RemotePort远程计算机端口号两个参数),然后客户机便处于正在连接服务器状态,等待服务器的响应。客户机调用Connect 方法触发了服务器Connect
48、Request事件,这时服务器端可以在此事件中判断是否要接受客户机的请求,如要就调用Accept 方法,并置标志位说明已成功连接客户机。服务器端调用Accept方法后又触发了客户机端Connect 事件,说明服务器端接受客户端的请求,双方已经建立连接了,这时再置客户机端的标志位,这就是一个完整的连接过程。当服务器或客户机调用Close 方法关闭连接时,都会触发对方的Close 事件,使其关闭连接。另外建立连接后发送数据的情况是客户机通过调用SendData方法发送数据给服务器,会触发服务器端的DataArrival事件,在这个事件中,服务器端可以调用GetData或 PeekData方法把客户
49、机发来的数据保存起来。服务器给客户机发信息同理。要注意一点的是,在服务器的Close事件中应该加上继续监听的代码,这样客户机才可以继续呼叫服务器。Winsock 控件实现多机互连方案下面是实现多机互连的三种方案。这里以三台机(分别命名为1 号机、2 号机和 3 号机)为例介绍。方案一:一台机作为服务器,其余两台机作为客户机1 号机作为服务器,用一个Winsock控件数组负责监听客户机的呼叫请求并用来与客户机建立连接。用TcpServer(2)和 TcpServer(3)两个 Winsock控件数组分别与2 号机和 3 号机建立连接。这里采用的是动态加载和卸载Winsock 控件数组来实现连接的
50、,也就是服务器一定要开着,下面的客户机才能与其通过Winsock 控件实现通讯,当服务器已经与其中的一台建立连接后,其它客户机还要呼叫服务器时,服务器就会加载新的Winsock 控件来与其建立连接,当客户机退出连接时,服务器再卸载该Winsock控件。服务器建立连接时是根据客户机的 IP 地址来接受响应的,所以可以方便的区分不同客户机的呼叫请求。不过这种方案会遇到一些问题:比如只要服务器关闭,其它客户机之间就无法进行数据交换了,而在服务器开的情况下,可以通过服务器的转发来完成客户机之间的数据交换。方案二:三台机同时作为服务器和客户机1 号机、2 号机和 3 号机没有层次等级之分,采用C/S 模