用VB编写网络寻呼 河南省南阳市 岳兵   提起ICQ的大名,爱好电脑的朋友一定不会感到陌生的吧?ICQ就是互联网上的寻呼机,无论什么时候,只要你的朋友在线,你只需在ICQ中输入他的ID号码,你就可以在互联网上呼到他。ICQ由于其方便、快捷,且拥有众多的注册用户而一举成为互联网上最流行的网络寻呼机,它几乎成为每一个上网用户的必备之物。当你在使用ICQ的时候,是否会想过自己动手编写一个网络寻呼机呢?这其实在VB中就可以实现。 
  网络寻呼的原理就是当客户端程序连接服务器时,通过服务器搜索所要呼叫的ID号码,如果检测到此用户且该用户正处于联网状态,则服务器通知此用户的客户端程序响应主叫方客户端程序,然后在主叫方和被叫方建立连接后,双方就可以聊天或进行其它的通信。 
  在VB中编写网络寻呼机需要建立两个程序,一个为客户端程序Client,一个为服务器端程序Server。   一、在Client工程中建立一个窗体,加载WinSock控件,称为tcpClient,协议选择TCP。再加入四个文本框,用以输入服务器的IP地址、服务器端口号,被呼叫的网络寻呼ID号以及用户登录ID号。然后再在窗体中加入三个按钮,分别命名为“连接”、“断开”和“退出”,点击“连接”按钮,并进行如下初始化连接,代码如下:  Private Sub Command1_Click() 
  If Len(Text1.Text) = 0 And Len(Text2.Text) = 0 Then 
   MsgBox ("请输入主机名或主机IP地址。") 
   Exit Sub 
  ElseIf Len(Text1.Text) > 0 Then 
   tcpClient.RemoteHost = Text1.Text 
   tcpClient.RemotePort = Text2.Text 
  End If 
  tcpClient.Connect 
  Timer1.Enabled = True 
 End Sub  Private Sub Command2_Click() 
  tcpClient.Close   '断开连接 
 End Sub  Private Sub Command3_Click() 
  End 
 End Sub  Private Sub Form_Load() 
  Text2.Text = "1001" 
 End Sub  Private Sub tcpClient_Connect() 
  tcpClient.SendData (Text3.Text&"@"&Text4.Text) 
 End Sub  Private Sub tcpClient_DataArrival(ByVal bytesTotal As Long) 
  Dim strData As String 
  tcpClient.GetData strData 
  strData = strData + "呼叫" 
  '在收到呼叫消息后弹出一对话框并显示主叫方ID号码 
  MsgBox (strData) 
 End Sub   二、在服务器端Server工程中也建立一个窗体,加载WinSock控件,称为tcpServer,协议选择TCP,设置其Index值为0,并在工程中添加模块。   内容如下:  Private Type ActiveUser 
  ClientIP As String '记录客户的IP地址 
  ClientPort As Integer '记录当前会话的端口 
  ClientID As Long '记录客户的ID号码 
  ClientConnected As Boolean '客户连接状态,True表示已连接,False表示没有连接 
 End Type 
 Dim CurUser() As ActiveUser 
 Dim tcpIndex As Integer '跟踪当前建立连接数   在Form_Load事件中加入如下代码:  Private Sub Form_Load() 
  tcpServer(0).Protocol = sckTCPProtocol 
  tcpServer(0).LocalPort = 1001 '将 LocalPort 属性设置为一个整数。 
  tcpServer(0).Listen '然后调用 Listen 方法。 
  tcpIndex = 1 
 End Sub   准备应答客户端程序的请求连接,使用ConnectionRequest事件来应答户端程序的请求,代码如下: 
 Private Sub tcpServer_ConnectionRequest (Index As Integer, ByVal requestID As Long) 
  Dim i As Integer 
  On Error GoTo ErrHandle 
  For i = 1 To tcpIndex '选择一个空闲端口 
   If CurUser(i).ClientConnected = False And i <> tcpIndex Then 
    Load tcpServer(i) 
    tcpServer(i).LocalPort = CurUser(i).ClientPort - 1 
    tcpServer(i).Accept requestID 
    Exit For 
   ElseIf CurUser(i).ClientConnected = False Then 
    Load tcpServer(i) 
    tcpServer(i).LocalPort = Port 
    If tcpServer(i).State <> sckClosed Then 
     tcpServer(i).Close 
    End If 
    tcpServer(i).Accept requestID 
    Exit For 
   End If 
   Next DoEvents 
   '测试连接是否成功 
   If tcpServer(i).State = sckConnected Then 
    If i = tcpIndex Then 
    '已经没有可用端口,记录客户的IP地址和端口号 
    tcpIndex = tcpIndex + 1 
    Port = Port + 1 
    ReDim Preserve CurUser(tcpIndex) 
    CurUser(i).ClientIP = tcpServer(i).RemoteHostIP 
    CurUser(i).ClientConnected = True 
    CurUser(i).ClientPort = Port 
    CurUser(tcpIndex).ClientConnected = False 
   Else 
    CurUser(i).ClientIP = tcpServer(i).RemoteHostIP 
    CurUser(i).ClientPort = Port 
    CurUser(i).ClientConnected = True 
   End If 
  End If 
  Exit Sub 
 ErrHandle: 
  Resume Next 
  '检查控件的 State 属性,如未关闭,在接受新的连接之前关闭此连接。 
  If tcpServer(0).State <> sckClosed Then 
   tcpServer(0).Close 
   tcpServer(0).Accept requestID '接受具有 requestID 参数的,连接。 
  End If 
 End Sub  Private Sub tcpServer_DataArrival(Index As Integer, ByVal bytesTotal As Long) 
  Dim i As Integer 
  Dim s As String 
  Dim RequID As Long '主叫方ID号码 
  Dim SearchID As Long '被叫方ID号码 
  On Error GoTo ErrHandle 
  tcpServer(Index).GetData s, vbString '接收数据并存入s  
  If Mid(s, i, 1) = "@" Then 
  '分离s中的主叫方和被叫方ID号码 
   SearhID = Left(s, i - 1) '把号存入mKey 
   RequID = Right(s, Len(s) - i) 'ID存入RequID 
  End If 
  '如果是请求寻呼某一ID号码,则检索当前此ID用户是否登录(即CurUser数组中是否存在此用户),然后发送信息,通知此用户响应呼叫并显示主叫用户ID号码。 
  For i = 1 To tcpIndex 
   If RequID = CurUser(i).ClientID And CurUser(i) .ClientConnected = True Then 
    tcpServer(i).SendData (SearhID) 
   End If 
  Next 
  Exit Sub 
 Sub ErrHandle: 
  If Err.Number = sckBadState Then '连接不正确 
   CurUser(i).ClientConnected = False 
   CurUser(i).ClientIP = "" 
   Unload tcpServer(i) 
   Resume Next 
  End If 
End Sub 

解决方案 »

  1.   

    用socket可以实现,但是现在代码不在这台机器里
    我的email:[email protected]
      

  2.   

    《 {在VB中利用UDP协议编写聊天程序} 》 {  UDP 协议是一种无连接协议,两台计算机之间的数据传输类似于传递邮件:消息从一台计算机发送到另一台计算机,但是两者之间没有明确的连接。 
      由于UDP 协议不需要显式的连接,就需要在两个Winsock控件中间发送数据,关键需要完成以下的三步: 
      1.将RemoteHost属性设置为另一台计算机的名称。 
      2.将RemotePort属性设置为第二个控件的LocalPort属性。 
      3.调用Bind方法,指定使用的LocalPort。 
      因为两台计算机的地位可以看成“对等的”,这种应用程序也被称为点对点的应用程序。 
      下面将创建一个聊天应用程序,两个人可以通过它进行实时的交谈。请按照以下步骤制作: 
      1.创建一个新的 Standard EXE 工程。将缺省的窗体的名称修改为frmPeerA,将窗体的标题修改为“Peer A”。 
      2.在窗体中放入一个 Winsock 控件,并将其命名为 udpPeerA。在“属性”页上,单击“协议”并将协议修改为 UDPProtocol。 
      3.在窗体中添加两个 TextBox 控件。将第一个命名为 txtSend,第二个命名为 txtOutput。 
      4.为窗体添加如下的代码。 
      Private Sub Form_Load() 
      ′控件的名字为udpPeerA 
      With udpPeerA 
      ′重点:必须将 RemoteHost 的值修改为对方计算机的名字。 
      RemoteHost= ″PeerB″ 
      RemotePort = 1001 ′连接的端口号。 
      Bind 1002 ′绑定到本地的端口。 
      End With 
      frmPeerB.Show′显示第二个窗体。 
      End Sub 
      Private Sub txtSend_Change() 
      ′在键入文本时,立即将其发送出去。 
      udpPeerA.SendData 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 伙伴,请按照以下步骤执行: 
      1.在工程中添加一个标准窗体,将窗体的名字修改为 frmPeerB,将窗体的标题修改为“Peer B”。 
      2.在窗体中放入一个 Winsock 控件,并将其命名为 udpPeerB。 
      3.在“属性”页上,单击“协议”并将协议修改为“UDPProtocol”。 
       4.在窗体上添加两个 TextBox 控件。将第一个命名为 txtSend,第二个命名为 txtOutput。 
      5.在窗体中添加如下代码 
      Private Sub Form_Load() 
      ′控件的名字为 udpPeerB。 
      With udpPeerB 
      ′重点:必须将RemoteHost的值改为对方计算机的名字。 
      RemoteHost= ″PeerA″ 
      RemotePort = 1002 ′要连接的端口。 
      Bind 1001 ′绑定到本地的端口上。 
      End With 
      End Sub 
      Private Sub txtSend_Change() 
      ′在键入后立即发送文本。 
      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 
      运行工程,然后在两个窗体的txtSend TextBox中分别键入一些文本。键入的文字将出现在另一个窗体的 txtOutput TextBox中。 
        
      

  3.   

    利用Winsock控件实现局域网通信 对于局域网用户中的编程爱好者来说,如果能自己编一个局域网通信程序,那么这一切将是多么美妙!可是,如果要从头开始完全由自己来编写一段用于通信的程序,必须对相关的网络协议及其他的一些较底层的技术有较深入的了解,这可不是一件容易的事。而现在有了Winsock控件,一切就不同了,它已经替你封装了所有烦琐的技术细节,并提供了访问TCP和UDP网络服务的方便途径。你只需通过设置控件的属性并调用其方法就可轻易连接到一台远程计算机中,并且还可以双向交换数据,而这一切都不需你了解TCP的细节或调用低级的Winsock APIs。 
      Winsock控件可以供Microsoft Acess、Visual Basic,Visual C++或Visual Foxpro的开发人员使用。本文以Visual Basic 6企业版为开发环境来向大家介绍一下Winsock控件的初步应用。   Winsock控件可以使用两种协议:TCP协议和UDP协议,下面来分别介绍。   TCP协议即数据传输协议,它允许创建和维护与远程计算机的连接,使其彼此可以进行数据传输。利用TCP协议通讯必须分别建立客户应用程序和服务器应用程序。   在创建客户应用程序时,必须知道服务器计算机名或其IP地址(存于RemoteHost属性)、及服务器计算机进行侦听的端口(存于RemotePort属性),然后调用Connect方法。   创建服务器应用程序时,就应相应设置一个侦听端口(LocalPort属性)并调用listen方法。当客户机需要连接时(connect),就会发生ConnectionRequest事件。为了完成连接,你可以在ConnectionRequest事件中调用Accept方法。建立连接后,任何一方计算机都可以发送、接收对方数据。如果你要发送数据,需调用SendData方法。当接收到数据时,会发生DataArrival事件,调用DataArrival事件中的GetData方法就可以获得对方传送的数据。   说了这么多,大家可能还是不太了解,让我用程序来详细说明。   如果只有两台计算机,那十分容易。假设甲机为客户机,乙机为服务器,且其IP为192.192.192.1,接收端口为1200(任意选一个未被使用的端口即可)。首先在甲机客户端程序中加入一个Winsock控件,起名为sckconnect,并设置其属性:RemoteHost=“192.192.192.1”,(即甲机IP地址), RemotePort=1200(即甲机侦听端口);再在乙机服务器程序中假如一个名为sckserver(0)的Winsock控件,其LocalPort=1200,   在乙机服务器程序中Form_Load()加入   sckserver(0).bind sckserver(0).LocalPort '与本地端口绑定   sckserver(0).listern ' 侦听   如果要传输数据,两机必须先建立连接。建立连接的程序如下:   甲机客户机要先请求连接   sckconnect.connect sckconnect.RemoteHost, sckconnect.RemotePort   此句执行时会触发服务器程序中的ConnectRequest事件,在此过程中决定是否建立连接,其代码如下:   Private sub sckserver_connectionrequest(index as Integer,Byval requestid as long)   if sckserver.count=1 then   load sckserver(1)   sckserver(1).accept requestId   end if   end sub   连接建立好以后,甲机或乙机都可以应用SendData方法来传送数据。例如,如果是甲机要传送一个叫string的字符串,只需在代码中加入:   sckconnect.SendData string   甲机传送数据后,会触发乙机的DataArrival事件,在其过程中用GetData方法可以收到传送的数据:   Private sub sckserver_DataArrival(Index as integer,Byval BytesTotal as long)   dim sdata as string   sckserver(1).GetData sdata,vbstring   end sub   最后别忘了在关闭程序前要先关闭Winsock控件   privat sub form_unload(cancel as integer)   if sckconnect.state <>sckclosed then   sckconnect.close   end if   end sub     这只是最简单的情况,如果有多台计算机,那就稍微复杂一些,客户端程序可以不做改动,而服务器端程序需要略做改动:   Private sub sckserver_connectrequest(Index as Integer,Byval requestid as long)   dim sip as string   dim I as integer   sip=sckserver(0).RemoteHostIP '获得登录者的IP地址   I=1   Do while I<=sckserver.ubound '检查是否已经有该地址的记录   If sckserver(I).RemoteHostIP=sip then '如有,不必加载新的控件   Sckserver(I).Accept requestid   Exit sub   End if   I=I+1   Loop   Load sckserver(I) '否则,加载新的控件   Scksrver(I).accept requestID   End sub   注意到:以上的信息交谈实际上都发生在客户机与服务器之间,如果要做成聊天室那样,每个人的话都可以被别人“听到”,那就要在服务器端的DataArrival事件中,把接收到的客户机传来的数据,转发给所有客户机即可。   其循环转发信息的代码如下:   For I=1 to sckserver.count   if sckserver(I).state<>sckclosed then   sckserver(I).SendData sdata   end if   next I     怎么样,这样我们就作好了自己的通信软件!     不过,不知大家注意到没有,上述程序都需要有一台计算机做为服务器,但如果我们的局域网中没有哪台计算机是可以常开的,也就是说,如果服务器端程序没有运行的话,其他客户端程序也没有办法通信。而这种情况却可能是经常出现的!至少,我所用的局域网那就是这样的。难道这样我们就无法享受局域网通信的乐趣了吗?   不要急,记得吗,我们的Winsock控件还有另一个主角:UDP协议。   UDP协议也称为用户数据报文协议,是一个无连接协议。何谓无连接协议?就是说利用此协议连接时,不必象TCP协议那样:需要服务器端侦听,客户机端请求连接,服务器端建立连接后双方才能通信。另外,UDP应用程序可以是客户机,也可以是服务器程序,而不必向TCP应用程序那样必须分别建立客户机程序和服务器程序。   下面,来简述一下UDP协议通信的过程:UDP协议中,为了在甲乙两机中传输数据,必须先分别设置两机的LocalPort属性;再将甲机的RemoteHost属性设置为乙机的IP地址,RemotePort属性设置为乙机的LocalPort属性值,此时甲机调用SendData方法就可以传送数据了,乙机同样使用DataArrival事件中的GetData方法来获取甲机发送给乙机的信息。如想乙机向甲机传送数据,只需仿照上面的过程设置即可。   用UDP协议来传输信息较TCP协议来说简单的多,它无须侦听(LISTEN),也无须请求连接(CONNECT),就象我们平时发信一样,只要写好地址及收信人姓名并发送出去即可。我们可以借此来编写一个局域网中的信息传送程序,下面来简单介绍以下程序中想实现的功能及其基本思想:   首先,我们一定想让程序的图标显示在system tray中而不显示在任务栏中吧!这要是自己编程实现可不是太容易,幸好VB光盘中在common oolsvbunsupportsystemTray 中有一个现成的程序,我们只要把它编译成systray.ocx 控件,然后在编写自己的程序时添加此控件即可。其使用方法十分简单,它已经定义好了鼠标单击、双击等事件,你只需编写相应的鼠标事件即可,这里不再多说。   程序的关键是:UDP协议在通讯时要知道对方的IP和Port,这要如何实现呢?最简单的方法是建立一个配置文件,里面放置了局域网上每台计算机的名字、IP和Port,在程序初始化时读出所有信息,在程序中只要知道向谁通信,读出其对应的IP和Port即可。   我们知道了每台计算机的IP和Port,但我们怎样才能知道其它计算机是否在线呢,否则发出信息别人收不到怎么办?我们可以把此程序放在启动菜单中,让其一开机就自动启动,并最小化,放于窗口右下角的system tray中。在程序刚开始运行时,它会自动向它从配置文件中所知道的所有IP发一条信息:“我来了!”,如果有计算机在线,它会自动返回一条信息:“欢迎!”,如此则两机通信成功,它们会分别把对方的名字加入到自己的可通信人名单中去;如果有计算机关机,程序在退出之前会自动向所有人告别:“再见!”,接收到此信息的计算机会自动把发送信息的计算机的名称从自己的可通信人名单中去除。这样,如果某人不在线,你将无法发送信息给它;如果除了你以外,其他人都没有开机,那你的可发送人名单中将没有任何人。而其它人只要一上线,会自动去你那里“登记”,其他人只要一离线,会自动去你那里“告别”,你可以据此知道他人是否正在使用计算机,你甚至可以以此程序来统计他人的每天上机时间,不错吧!   好了,一个局域网通信的程序的基本模型已经有了,并不复杂吧!大家赶快动手吧,来享受用自己的程序来聊天的乐趣!   不过,要想编写一个出色的程序,不光是要有良好的创意与功能,更重要的是程序的兼容性与容错性。本例中,对错误处理没有做详细的解释,关于这一点,大家可以在Winsock控件的error事件及其帮助中找到满意的答案。   另外,还可以从以下几方面来考虑功能的扩充:如传送图形、声音等多媒体信息、局域网互传文件(主动传送)、历史通话记录、系统日志、个人上机时间统计等等,而所有的这一切仅仅取决于你的想象力与你的聪明才智!下面,笔者以传送文件为例来讲一讲其功能实现的代码。   你可以把本地的文件(图形、声音等可以先存成临时文件)以二进制文件的方式来打开它,将其内容全部读入一个byte类型的数组中,本地机代码如下:   dim myfile () as byte   dim position as long   open "filename" for binary as #1   position=0   do while not eof(1)   position=positon+1   redim preserve myfile (1 to position)   get #1,,myfile(position)   loop   close #1   再向远程机传送这个字节数组   sckserver.SendData myfile   远程机收到这个数组之后,再以二进制文件的方式打开一个新目标文件,将数组内容写入这个新打开的文件,如果是bmp图片就将其放入picture图片框中,如果是wav文件,就播放。这样,局域网中的两个人就可以通过语言、图片、文字来交流了。   远程机代码如下:   Private sub sckconnect_DataArrival(byval bytestotal as long)   dim receivefile(1 to bytestotal)as byte   sckconnect.GetData receivefile,vbarray+vbbyte   '告诉Winsock控件收到的是字节数组类型的数据   open "c: emp文件名" for binary as #1   for I=1 to bytestotal   put #1,,remotearray(I)   next I   clost #1   end sub 
      

  4.   

    to:Yan5453() (2002-1-24 22:13:28)  得0分 
    大家都提了很多,但你知道吗?现在这种软件很多很多,为什么不做些有用的东西呢?  你能有什么别人没做过(有用户、不脱离实际的)的东西吗?
    现在不是说这个东西多不多的问题!有不有用,二是你能把同样的东西做得更有你的风格
    更能体贴用户!让用户觉得你软件是专业、也很friend的!