本人使用Winsock做了两个通讯程序(一个客户端[运行在电脑A上],一个服务器端[运行在电脑B上]),客户端程序上只有一个按钮(“发送”)控件、一个按钮(“退出”)控件、一个Winsock控件(名称为:tcpClient)和一个文本框控件Text1,服务器端程序上只有一个文本框控件Text1,一个Winsock控件(名称为:tcpServer),现在程序要实现的功能就是在客户端的文本框Text1中输入数据信息‘abcde’,然后点击“发送”按钮,那么在服务器端上的文本框Text1中则会马上显示出客户端发送过来的信息‘abcde’,现在这个功能我已经实现了,不过必须是建立在下面的这个条件上的:两个程序必须要先运行电脑B上的服务器端程序,然后再运行电脑A上的客户端程序!如果说,我在连接建立好了(可以成功发送数据)之后,突然将客户端程序退出,然后再运行这个客户端程序的话,在文本框中输入“12345”,再点击“发送”按钮的话,则会报错:{实时错误40006,所需事物或请求的错误协议或连接状态}!上面的这样肯定是不行的啊,所以我希望这个程序能够实现以下功能:如果客户端程序退出的话,只要再次打开它运行了之后,客户端程序依然能够正常的发送数据,如果是服务器端程序一端退出的话,只要再次打开它运行了之后,服务器端程序依然能够正常的接收数据,而且在任意一端退出的时候,都能让另一端程序知道。不知道有什么办法可以解决?请高手指点,提供一些源代码供小弟参考!谢谢!附:请问哪位大侠有关于Winsock通讯的书籍吗?最好是电子版的,本人因为是刚接触Winsock,所以请各位帮帮忙,,不胜感激!!!下面我贴出我的代码:客户端程序的代码: (运行在电脑A上)
Private Sub Command1_Click()         '发送按钮
   tcpClient.SendData Trim(Text1.Text)
End SubPrivate Sub Command2_Click()         '退出按钮
   tcpClient.Close
   Unload Me
End SubPrivate Sub Form_Load()
   tcpClient.Protocol = sckTCPProtocol
   tcpClient.RemoteHost = "192.168.1.52"
   tcpClient.RemotePort = 1001
   tcpClient.Connect
End Sub服务器端程序的代码:(运行在电脑B上)
Private Sub Form_Load()
    tcpServer.Protocol = sckTCPProtocol
    tcpServer.LocalPort = 1001
    tcpServer.Listen
End SubPrivate Sub tcpServer_ConnectionRequest(ByVal requestID As Long)
    If tcpServer.State <> sckClosed Then
       tcpServer.Close
    End If
    tcpServer.Accept requestID
End SubPrivate Sub tcpServer_DataArrival(ByVal bytesTotal As Long)
    Dim strData As String
    tcpServer.GetData strData
    Text1.Text = strData
End Sub

解决方案 »

  1.   

    建服务端(B机器)中的windsock用一个做为监听,接到连接申请load一个做连接(用winsock数组)当客户端非正常退出再连接时也不会因为服务端端还在用而出错而且我没看到你有对客户端退出做处理
      

  2.   

    Private Sub tcpServer_Close()
        if tcpServer.State<>0 then tcpServer.Close
        tcpServer.Protocol = sckTCPProtocol
        tcpServer.LocalPort = 1001
        tcpServer.Listen
    End Sub
      

  3.   

    我的处理:服务器:
    一个socklisten:监听
    一个sockserver:响应监听得到请求以后,测试响应是否空闲,是则由响应(sockserver)响应,否则阻塞而一旦出错,就关闭响应,变成空闲状态这样就可以响应客户端的请求了因为TCP/IP协议是有连接协议,一旦连接不正常,其state<>7
      

  4.   

    我个人认为会用WINSOCK控件之后,还是最好转向WINDOWS SOCKET API。
    微软认为用VB的人都头脑简单,所以包装的过了分了。所以我们都不知道底层下的细节。所以要快点“断奶”。等精通WINSOCK控件,最还还是学用API.
      

  5.   

    >我希望这个程序能够实现以下功能:如果客户端程序退出的话,只要再次打开它运行了之后,客户端程序依然能够正常的发送数据,如果是服务器端程序一端退出的话,只要再次打开它运行了之后,服务器端程序依然能够正常的接收数据,而且在任意一端退出的时候,都能让另一端程序知道。1 服务器未运行时,客户端启动用一个Timer,定时检查
    Private Sub tmrWinsock_Timer()On Error GoTo ErrExit
    If clSock.State <> 7 Then tcpClient.Connect
    Exit SubErrExit:
    End Sub2 消息加标签客户端程序的代码: (运行在电脑A上)
    Private Sub Command1_Click()         '发送按钮
       If tcpClient.State <> 7 Then
          Msgbox "未建立连接"
          Exit Sub
       End If
       tcpClient.SendData "D:" & Trim(Text1.Text)
    End SubPrivate Sub Command2_Click()         '退出按钮
       tcpClient.SendData "M:Logoff"
       tcpClient.Close
       Unload Me
    End SubPrivate Sub tcpClient_DataArrival(ByVal bytesTotal As Long)
       Dim strData As String
       tcpClient.GetData strData
       If strData = "M:Logoff" Then tcpClient.Close '关闭,以便定时器事件中重新连接
    End Sub服务器端程序的代码:(运行在电脑B上)Private Sub tcpServer_ConnectionRequest(ByVal requestID As Long)
        If tcpServer.State <> sckClosed Then
           tcpServer.Close
        End If
        tcpServer.Accept requestID
    End SubPrivate Sub tcpServer_DataArrival(ByVal bytesTotal As Long)
        Dim strData As String
        tcpServer.GetData strData
        Select Case Left(strData, 2)
            Case "D:"
                Text1.Text = Mid(strData,3)
            Case "M:"
                If strData = "M:Logoff" Then
                   Text1 = "客户端断开"
                End If
        End Select
    End SubPrivate Sub Form_Unload()
       tcpServer.SendData "M:Logoff"
       tcpServer.Close
    End Sub
      

  6.   

    用TCP协议通讯时候,Client或者Server非正常断开的话,后面经常会连接不上,一个比较使用的方法就是随时检测Winsock控件的连接状态。比如加一个Timer控件
    if winosck1.state=sckclosing then '同级连接断开
        winsock1.close
        winsock1.listen
    end if
      

  7.   

    使用udp连接,然后定时检测b的状态------就是定时发送特定数据,要求b响应,
     如果a收到b的check表示b上线了,就可以再一次把你要发的数据再发送给b
      

  8.   

    在sock error事件中截取这个错误就ok