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命令触发不同的事件,然后分别处理事件。这不仅提高了程序的调试性和安全性,也符合事件驱动编程方法的特点。