A doubt about WinSock

I had a small doubt about Winsock! I created a small chat program using WinSock. The program works fine when I test it on my local machine but when I try to connect to a remote machine I end up with a run time error 40006.
Why does this happen? Could it be because of a firewall? I so how do i make it ask for the users permission to grant access for the required port? Or is there a better way of doing this

Thanks

Comments

  • If you call the SendData method in the WinSock control before the socket has been connected, you will receive the Microsoft Visual Basic Error:

    Run-time error: 40006

    "Wrong protocol or connection state for the requested transaction or request."

    CAUSE
    The code is trying to call the SendData method before the port has actually been connected. The Connect method in Visual Basic is asynchronous and is more like a request to connect to the Winsock port.

    RESOLUTION
    The code must wait until the Connect event is fired before attempting to call the SendData or GetData methods. The Connect event is a signal that the connect request has been accepted and the connection is established.

    STATUS
    This behavior is by design.

    http://support.microsoft.com/default.aspx?scid=kb;en-us;183987

    ------
    : I had a small doubt about Winsock! I created a small chat program using WinSock. The program works fine when I test it on my local machine but when I try to connect to a remote machine I end up with a run time error 40006.
    : Why does this happen? Could it be because of a firewall? I so how do i make it ask for the users permission to grant access for the required port? Or is there a better way of doing this
    :
    : Thanks
    :

    [red]Good luck![/red]
    [blue]Hackman[/blue]

  • Thanks for that reply.

    Now that I have added some error handling in the server code it does not work on my local machine either. I will post the code, hopefully some one can tell me what I am doing wrong.
    The code for the server is
    [code]
    Option Explicit

    Private Sub cmdSend_Click()

    Winsock.SendData txtChat.Text
    DoEvents
    txtMain.Text = txtMain.Text & vbCrLf & txtChat.Text
    txtChat.Text = ""
    End Sub

    Private Sub Form_Load()

    cmdSend.Enabled = False 'Added this to deal with error 40006
    Winsock.Protocol = sckTCPProtocol
    Winsock.LocalPort = 10101
    Winsock.Listen
    If Winsock.State = sckConnected Then
    MsgBox "the client is connected" 'Tried to check if the
    'server will return a message when connected, but it does not even
    'when my client returns a Connected message
    End If

    End Sub

    Private Sub Winsock_ConnectionRequest(ByVal RequestID As Long)

    Winsock.Close
    Winsock.Accept RequestID

    End Sub

    Private Sub Winsock_DataArrival(ByVal bytesTotal As Long)
    Dim strData As String
    Winsock.GetData strData
    txtMain.Text = txtMain.Text & vbCrLf & strData
    txtMain.SelStart = Len(txtMain.Text)

    End Sub

    Private Sub winsock_connect()
    cmdSend.Enabled = True 'I do not get this message even when I get a
    ' Connected msg from my client
    MsgBox "The client is connected"
    End Sub
    [/code]

    The code for the client is
    [code]
    Option Explicit

    Private Sub cmdConnect_Click()

    Winsock.Connect txtIP.Text, "10101"

    End Sub

    Private Sub cmdLocalHost_Click()
    MsgBox "The local host is:" & Winsock.LocalIP


    End Sub

    Private Sub cmdSend_Click()

    Winsock.SendData txtChat.Text
    DoEvents
    txtMain.Text = txtMain.Text & vbCrLf & txtChat.Text
    txtChat.Text = ""

    End Sub

    Private Sub Winsock_Connect()

    MsgBox "Connected"
    End Sub

    Private Sub Winsock_DataArrival(ByVal bytesTotal As Long)

    Dim strData As String
    Winsock.GetData strData
    txtMain.Text = txtMain.Text & vbCrLf & strData
    txtMain.SelStart = Len(txtMain.Text)

    End Sub

    Private Sub Winsock_Error(ByVal Number As Integer, Description As String, _
    ByVal Scode As Long, ByVal Source As String, ByVal HelpFile As String, _
    ByVal HelpContext As Long, CancelDisplay As Boolean)

    MsgBox "Error: " & Description

    End Sub

    [/code]

    Now when I run the client/server on my local machine I am able to send messages to the server, but the problem is that the send button on the server is disabled since the following event does not seem to occur
    Private Sub winsock_connect()
    cmdSend.Enabled = True
    MsgBox "The client is connected"
    End Sub

    But then how is this possible since only if the server/client are connected will the data be sent to the server right?

    I am totally lost any help would be greatly appreciated



    : If you call the SendData method in the WinSock control before the socket has been connected, you will receive the Microsoft Visual Basic Error:
    :
    : Run-time error: 40006
    :
    : "Wrong protocol or connection state for the requested transaction or request."
    :
    : CAUSE
    : The code is trying to call the SendData method before the port has actually been connected. The Connect method in Visual Basic is asynchronous and is more like a request to connect to the Winsock port.
    :
    : RESOLUTION
    : The code must wait until the Connect event is fired before attempting to call the SendData or GetData methods. The Connect event is a signal that the connect request has been accepted and the connection is established.
    :
    : STATUS
    : This behavior is by design.
    :
    : http://support.microsoft.com/default.aspx?scid=kb;en-us;183987
    :
    : ------
    : : I had a small doubt about Winsock! I created a small chat program using WinSock. The program works fine when I test it on my local machine but when I try to connect to a remote machine I end up with a run time error 40006.
    : : Why does this happen? Could it be because of a firewall? I so how do i make it ask for the users permission to grant access for the required port? Or is there a better way of doing this
    : :
    : : Thanks
    : :
    :
    : [red]Good luck![/red]
    : [blue]Hackman[/blue]
    :
    :

  • : [code]
    : Option Explicit
    :
    : Private Sub Form_Load()
    :
    : cmdSend.Enabled = False 'Added this to deal with error 40006
    : Winsock.Protocol = sckTCPProtocol
    : Winsock.LocalPort = 10101
    : Winsock.Listen
    : If Winsock.State = sckConnected Then
    : MsgBox "the client is connected" 'Tried to check if the
    : 'server will return a message when connected, but it does not even
    : 'when my client returns a Connected message
    : End If
    :
    : End Sub
    [/code]

    At this point your server socket is just listening, so the State will never be sckConnected. Form_Load then ends and this code is not called again until the form is loaded again.

    [code]
    : Private Sub Winsock_ConnectionRequest(ByVal RequestID As Long)
    :
    : Winsock.Close
    : Winsock.Accept RequestID
    :
    : End Sub
    [/code]

    Perhaps I'm mistaken, but doesn't Winsock.Close make the socket stop listening? That would explain why you never get a Connect event - it appears that you're telling the server socket to close, which would make the .Accept meaningless (if not an outright error).

    [code]
    : Private Sub Winsock_DataArrival(ByVal bytesTotal As Long)
    : Dim strData As String
    : Winsock.GetData strData
    : txtMain.Text = txtMain.Text & vbCrLf & strData
    : txtMain.SelStart = Len(txtMain.Text)
    :
    : End Sub
    :
    : Private Sub winsock_connect()
    : cmdSend.Enabled = True 'I do not get this message even when I get a
    : ' Connected msg from my client
    : MsgBox "The client is connected"
    : End Sub
    : [/code]
    :
    : The code for the client is
    : [code]
    : Option Explicit
    :
    : Private Sub cmdConnect_Click()
    :
    : Winsock.Connect txtIP.Text, "10101"
    :
    : End Sub
    :
    : Private Sub cmdLocalHost_Click()
    : MsgBox "The local host is:" & Winsock.LocalIP
    :
    :
    : End Sub
    :
    : Private Sub cmdSend_Click()
    :
    : Winsock.SendData txtChat.Text
    : DoEvents
    : txtMain.Text = txtMain.Text & vbCrLf & txtChat.Text
    : txtChat.Text = ""
    :
    : End Sub
    :
    : Private Sub Winsock_Connect()
    :
    : MsgBox "Connected"
    : End Sub
    :
    : Private Sub Winsock_DataArrival(ByVal bytesTotal As Long)
    :
    : Dim strData As String
    : Winsock.GetData strData
    : txtMain.Text = txtMain.Text & vbCrLf & strData
    : txtMain.SelStart = Len(txtMain.Text)
    :
    : End Sub
    :
    : Private Sub Winsock_Error(ByVal Number As Integer, Description As String, _
    : ByVal Scode As Long, ByVal Source As String, ByVal HelpFile As String, _
    : ByVal HelpContext As Long, CancelDisplay As Boolean)
    :
    : MsgBox "Error: " & Description
    :
    : End Sub
    :
    : [/code]
    :
    : Now when I run the client/server on my local machine I am able to send messages to the server, but the problem is that the send button on the server is disabled since the following event does not seem to occur
    : Private Sub winsock_connect()
    : cmdSend.Enabled = True
    : MsgBox "The client is connected"
    : End Sub
    :
    : But then how is this possible since only if the server/client are connected will the data be sent to the server right?
    :
    : I am totally lost any help would be greatly appreciated

    Assuming the client got a Connect event it could conceivably send data to the server, though there isn't any guarantee I know of that the server will get it. I'm still bothered by that Winsock.Close in the server. I could be mistaken, but that seems to be a likely culprit of the odd behavior.


    [size=5][italic][blue][RED]i[/RED]nfidel[/blue][/italic][/size]

    [code]
    $ select * from users where clue > 0
    no rows returned
    [/code]

  • [b][red]This message was edited by infidel at 2005-2-23 15:23:15[/red][/b][hr]
    : [code]
    : : Private Sub Winsock_ConnectionRequest(ByVal RequestID As Long)
    : :
    : : Winsock.Close
    : : Winsock.Accept RequestID
    : :
    : : End Sub
    : [/code]
    :
    : Perhaps I'm mistaken, but doesn't Winsock.Close make the socket stop listening? That would explain why you never get a Connect event - it appears that you're telling the server socket to close, which would make the .Accept meaningless (if not an outright error).

    I guess I was mistaken. A listening socket can't accept a connection, and the socket accepting the connection request doesn't get a Connect event.

    I made a chat-type server like this a while back. One tip I'll give you is to make your Winsock control a control array by setting it's Index = 0. Now, Winsock1(0) can keep listening while you Load Winsock1(n) to .Accept a ConnectionRequest. That's the simplest way to allow multiple clients.

    Here is the most trivial Client I can think of:

    [code]
    Private Sub Form_Load()

    Winsock1.RemoteHost = "localhost"
    Winsock1.RemotePort = 80
    Call Winsock1.Connect

    End Sub

    Private Sub Winsock1_Connect()

    Winsock1.SendData "Hello from client"

    End Sub

    Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)

    Dim strData As String

    Winsock1.GetData strData, , bytesTotal
    Text1.Text = Text1.Text & vbCrLf & strData

    End Sub
    [/code]

    And a trivial Server:
    [code]
    Private Sub Form_Load()

    With Winsock1(0)
    .LocalPort = 80
    .Listen
    End With

    End Sub

    Private Sub Winsock1_Close(Index As Integer)

    With Winsock1(Index)
    .Close
    End With

    Unload Winsock1(Index)

    End Sub

    Private Sub Winsock1_ConnectionRequest(Index As Integer, ByVal requestID As Long)

    Dim intNext As Integer: intNext = Winsock1.Count

    Load Winsock1(intNext)
    With Winsock1(intNext)
    Call .Accept(requestID)
    Call .SendData("Hello from server")
    End With

    End Sub

    Private Sub Winsock1_DataArrival(Index As Integer, ByVal bytesTotal As Long)

    Dim strData As String

    With Winsock1(Index)
    .GetData strData, , bytesTotal
    Me.Text1.Text = Me.Text1.Text & vbCrLf & strData
    End With

    End Sub
    [/code]

    I'll leave it as an exercise for you to figure out how to enable further communication beyond the simple greeting message, and to figure out how to manage the winsock array more intelligently.

    [size=5][italic][blue][RED]i[/RED]nfidel[/blue][/italic][/size]

    [code]
    $ select * from users where clue > 0
    no rows returned
    [/code]



  • [b][red]This message was edited by eternities_end at 2005-2-26 18:26:5[/red][/b][hr]
    Thanks for the reply infidel
    I was just wondering what the following code did
    [code]
    With Winsock1(intNext)
    Call .Accept(requestID)
    Call .SendData("Hello from server")
    End With
    [/code]
    What does the "call" do? Can't I just use it as
    [code]
    With Winsock1(intNext)
    .Accept(requestID)
    .SendData("Hello from server")
    End With
    [/Code]



    One more small doubt, I have read a few tutorials on winsock programing and all of them have one point in common and that is not use a port specified by the IANA ie the ports from 1-1023. Why is this?

    Thanks


  • Corrct me If i'm wrong but i believe your not supposed to use these prots because they are commonly used for commercial programs such as Internet explorewr or Microsoft update and such. this means you should stick tot he higher ports because these aren't really reserved Persay. Once again I'm not expert at this so i could be wrong but im pretty sure thats why.
    [code]If Userclue > 0 then
    msgbox("Woohoo that Makes one")
    end if[/code]
    So... How long do you think you'll be waiting?
    Im not Sen[red]d[/red]ing Sumbl[red]i[/red]minal m[red]e[/red]ssages

  • : [b][red]This message was edited by eternities_end at 2005-2-26 18:26:5[/red][/b][hr]
    : Thanks for the reply infidel
    : I was just wondering what the following code did
    : [code]
    : With Winsock1(intNext)
    : Call .Accept(requestID)
    : Call .SendData("Hello from server")
    : End With
    : [/code]

    It uses the next winsock in the array to accept the connection request, leaving the original winsock free to listen for more clients. It then sends a brief message to the client so the client knows the server is ready.

    : What does the "call" do? Can't I just use it as
    : [code]
    : With Winsock1(intNext)
    : .Accept(requestID)
    : .SendData("Hello from server")
    : End With
    : [/Code]

    Technically yes, it's one of those odd VB-isms. Better to use Call, though, IMO.

    : One more small doubt, I have read a few tutorials on winsock programing and all of them have one point in common and that is not use a port specified by the IANA ie the ports from 1-1023. Why is this?

    Certain port numbers are reserved for specific services. It's why you generally don't ever have to enter port 80 into your web browser. All browsers know that the HTTP port is 80.


    [size=5][italic][blue][RED]i[/RED]nfidel[/blue][/italic][/size]

    [code]
    $ select * from users where clue > 0
    no rows returned
    [/code]

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories