VB VB高手,快来看看~
/06/0407/14/2e 46 bb 930009159s . html
用VB5中的WinSock控件编写在线聊天程序
套接字是在Unix系统上提出的。起初,它主要用于本地通信,但很快应用于C/S系统。在此基础上,微软创建了WinSock控件,专门用于Windows界面,完全兼容Sockets。Winsock控件对用户是不可见的,它提供了一种访问TCP和UDP网络服务的便捷方式。微软Access,Visual Basic,Visual C++或者Visual FoxPro的开发者都可以使用。要编写客户端或服务器应用程序,不需要了解TCP的细节,也不需要调用底层的Winsock APIs。通过设置控件的属性并调用其方法,可以轻松地连接到远程计算机,并且还可以双向交换数据。下面用VB5中的WinSock控件写一个在线聊天程序。
1)网络通信协议的基础和选择
1.1 TCP(数据传输协议)基础
数据传输协议允许您创建和维护与远程计算机的连接。连接两台计算机可以互相传输数据。
如果创建客户端应用程序,则必须知道服务器计算机名或IP地址(RemoteHost属性)以及侦听的端口(RemotePort属性),然后调用Connect方法。
如果创建一个服务器应用程序,应该设置一个监听端口(LocalPort属性)并调用listen方法。当客户端计算机需要连接时,ConnectionRequest事件发生。若要完成连接,可以在ConnectionRequest事件中调用Accept方法。
连接建立后,任何计算机都可以发送和接收数据。若要发送数据,可以调用SendData方法。DataArrival事件在收到数据时发生。您可以通过调用DataArrival事件中的GetData方法来获取数据。
1.2 UDP(用户数据报协议)基础
用户数据报协议(UDP)是一种无连接协议。与TCP不同,计算机不建立连接。此外,UDP应用程序可以是客户端或服务器。
为了传输数据,您必须首先设置客户端计算机的LocalPort属性。然后,服务器计算机只需要将RemoteHost设置为客户端计算机的Internet地址,将RemotePort属性设置为与客户端计算机的LocalPort属性相同的端口,调用SendData方法开始发送信息。因此,客户端计算机使用DataArrival事件中的GetData方法来获取发送的信息。
1.3选择通信协议
使用WinSock控件时,首先要考虑的是使用什么协议。可以使用的协议包括TCP和UDP。这两种协议的重要区别在于它们的连接状态:
TCP协议是一种连接协议,可以和电话系统相提并论。在开始数据传输之前,用户必须建立连接。
UDP协议是一种无连接协议,两台计算机之间的传输类似于邮件的传递:消息从一台计算机发送到另一台计算机,但它们之间没有明确的连接。此外,一次传输的最大数据量取决于具体的网络。
选择哪种协议通常由需要创建的应用程序决定。以下问题将有助于选择合适的协议:
1.在发送和接收数据时,应用程序需要从客户端或服务器获得确认信息吗?如有必要,在发送和接收数据之前,使用TCP协议建立清晰的连接。
2.数据量是否特别大(比如图像和声音文件)?连接建立后,TCP协议会维护连接并保证数据的完整性。然而,这种连接需要更多的计算资源,因此它是“昂贵的”。
3.数据传输是间歇的还是在一个会话中?例如,如果应用程序需要在任务完成时通知计算机,UDP协议更适合。UDP协议适用于发送少量数据。
通信协议的选择通过设置WinSock的协议属性来实现。选择TCP通信协议编写在线聊天程序。在此之前,你必须知道一个极其重要的参数——服务器的IP地址或计算机名。
2)确定计算机的名称
1.在计算机桌面上,右键单击“网上邻居”。
2.选择“属性”。
3.单击徽标选项卡。
4.您可以在“计算机名称”框中找到计算机的名称。
确定计算机的IP地址
1.单击任务栏上的开始。
2.选择“运行”。
3.如果服务器端操作系统是win95,则在“Open”中填写“winipcfg”,如果服务器端操作系统是winnt,则在“Open”中填写“ipconfig”。
4.按下“确定”键。
上面找到的计算机名或IP地址可以用作WinSock的RemoteHost属性的值。
winsock控件的状态属性。
state属性的设置值为:常量。
价值描述
Sckclosed 0默认值。关闭
Sckopen 1打开
听力2
Sckconnectionpending 3连接已挂起
Sckresolvinghost 4标识主机。
Sckhostresolved 5已识别出主机。
Sckconnecting 6正在连接。
Sckconnected 7已连接。
Sckclosing 8 peer正在关闭连接。
Sckerror 9错误
下面主要使用两个状态属性的值:sckClosed.sckConnected。
4)在线聊天程序的编程
4.1程序中服务器的作用。
从图中可以看出,服务器端的两个winsock控件之间没有直接通信,sckServer1和sckClient2之间以及sckServer2和sckClient1之间也没有直接通信。也就是说,如果sckClient1向sckClient2发送一条消息,该消息首先被sckServer1接受,然后传输到程序的信息处理部分,信息处理部分再将处理后的消息传输到sckServer2,再传输到sckClient2。反之亦然,从达拉斯到礼堂,那么服务器的信息处理部分是做什么的呢?
1.对沟通渠道的数量做一些限制。
2.使用后关闭的通道必须重新使用以节省资源。
3.必须区分传输的分组信息,以便进行不同的处理。
不同的信息可以通过解包数据的报头来区分。
网上聊天有两种方式:一是通过广播;第二,以点对点的方式。广播模式意味着所有客户都可以接收到一个客户发送的信息。点对点模式是指一对想要“交头接耳”的客户专门开了一个“小屋”进行交谈,其他客户无法“听”到他们的对话。在下面的节目中,我们将看到如何利用不同的数据头(点对点数据的头是“PT”,广播模式没有头)来区分用户是想以广播模式通话还是点对点模式通话。
4.2客户端程序
1.在客户机上创建一个新项目,并将其命名为“ClientPrj”。
2.将默认表单命名为frmClient。
3.将表单的标题更改为“客户”。
4.向窗体中添加一个WinSock控件,并将其命名为tcpClient。
5.在frmClient中添加ListBox控件。将其命名为lstReceive。
6.在frmClient中添加TextBox控件。命名为txtSend。
7.在窗体上放置两个CommandButton控件,并将其命名为cmdConnect和cmdSent。
8.将cmdConnect控件的标题改为Connect,将cmdSent控件的标题改为Sent。
9.将下面的代码添加到窗体中。
Private Sub cmdConnect_Click()
出错时转到错误提示
sckClient。连接
出口接头
错误提示:
MsgBox "服务器没有打开或存在网络错误!"
结束
末端接头
Private Sub cmdSent_Click()
sckClient。SendData txtSent。文本
末端接头
私有子窗体_Load()
RemoteComputerName是服务器的计算机名或IP地址。
sckClient。RemoteHost = "RemoteComputerName "
sckClient。远程端口= 1000
末端接头
私有Sub sckClient_Close()
MsgBox“服务器通道关闭!”
结束
末端接头
私有Sub sckClient_Connect()
MsgBox "连接成功!"
cmdConnect。启用=假
末端接头
private Sub sck client _ data arrival(ByVal bytes total As Long)
将s作为字符串变暗
sckClient。GetData s
lstReceive。附加项目
末端接头
private Sub sck client _ Error(ByVal Number为整数,Description为字符串,ByVal Scode为Long,_ ByVal Source为字符串,ByVal HelpFile为字符串,ByVal HelpContext为Long,CancelDisplay为Boolean)
sckClient。关闭
cmdConnect。启用=真
末端接头
4.3服务器端程序
1.在服务器端创建一个新项目,并将其命名为“ServerPrj”。
2.将默认表单命名为“frmServer”。
3.向窗体中添加一个ListBox控件,并将其命名为“lstReceive”。
4.在窗体中添加三个WinSock控件,分别命名为“sckListen”、“sckBusy”和“sckServer”,并将“sckServer”的“Index”属性设置为0。
5.将下面的代码添加到窗体中。
最大通道数
Private MaxChan为整数
私有子窗体_Load()
将I标注为整数
MaxChan = 10
对于i = 1至MaxChan - 1
加载sckServer(i)
接下来我
sckListen。本地端口= 1000
sckListen。听
末端接头
私有Sub sckBusy_Close()
sckBusy。关闭
末端接头
private Sub sck busy _ data arrival(ByVal bytes total As Long)
SckBusy。SendData“服务器忙,请稍后连接!”
多项活动
末端接头
private Sub sck listen _ connection request(ByVal request id为Long)
将I标注为整数
决定哪个Winsock将接受请求。
对于i = 0至MaxChan - 1
如果sckServer(i)。那么状态= 0
为...退出
如果…就会结束
接下来我
如果sckServer(i)。那么状态= 0
sckServer(i)。接受requestID
出口接头
如果…就会结束
如果所有的Winsock都用完了,一个特殊的“忙”Winsock将接受请求,以防用户的请求没有得到响应。
sckBusy。关闭
sckBusy。接受requestID
末端接头
private Sub sck listen _ Error(ByVal Number为整数,Description为字符串,ByVal Scode为Long,_ ByVal Source为字符串,ByVal HelpFile为字符串,ByVal HelpContext为Long,CancelDisplay为Boolean)
sckListen。关闭
sckListen。本地端口= 1000
sckListen。听
末端接头
Private Sub sckServer_Close(索引为整数)
sckServer(索引)。关闭
末端接头
private Sub sck server _ data arrival(Index为整数,ByVal bytesTotal为长整型)
将s作为字符串变暗
将I标注为整数
sckServer(索引)。GetData s
Ifucase (left (trim (s),2))=“pt”然后‘判断是不是耳语,点对点的方式。
如果IsNumeric(Mid(Trim(s),3,1))则
i = Mid(Trim(s),3,1)
sckServer(i)。发送数据频道。指数和指数。”& amp右(修剪),镜头(修剪)- 3)
多项活动
如果…就会结束
“Else”广播模式
对于i = 0至MaxChan - 1
使用winsock的State属性向连接到服务器的所有客户端发送消息。
如果sckServer(i)。那么状态= 7
sckServer(i)。发送数据频道。指数和指数。”& amp修剪
多项活动
如果…就会结束
接下来我
如果…就会结束
lstReceive。AddItem频道。指数和指数。”& amp修剪
末端接头
private Sub sck server _ Error(Index为整数,ByVal号为整数,Description为字符串,_
ByVal Scode为Long,ByVal源为String,ByVal帮助文件为String,ByVal帮助上下文为_
Long,cancel显示为布尔值)
sckServer(索引)。关闭
末端接头
从节目中可以看出:第一,节目中限制了频道数(10个频道)。第二,通过判断WinSock控件的State属性是否为0(关闭状态),重用关闭的WinSock控件。第三,通过在WinSock控件发送的信息中添加头,可以对信息进行不同的处理(如果在程序中的信息前添加“PT”(私聊)+“频道数”的头,就可以知道该客户要和另一个拥有这个“频道数”的客户“耳语”,否则该信息将通过广播发送给所有客户)。
五)结束语
WinSock控件不仅用来编写在线聊天程序,还可以用来编写各种网络游戏或网络通讯程序。事实上,WinSock控件是编译各种C/S程序的利器。在实际使用中,WinSock控件通常封装在Activex DLL(进程内)和Activex EXE(进程外)组件(在类中引用)的类中使用。通过在传输的信息前面区分不同的头,由RaiseEvent命令触发不同的事件,然后分别处理事件。这不仅提高了程序的调试性和安全性,也符合事件驱动编程方法的特点。