Link to home
Start Free TrialLog in
Avatar of John Pumphrey, Crestron CTI, DMC-E
John Pumphrey, Crestron CTI, DMC-E

asked on

Winsock_DataArrival problems

I am having trouble with winsock's Data_Arrival event. I am getting the connection accepted signal but when I send data the event never fires. I have a print line at the beginning of the proceedure to tell me the event fired but I see nothing.
Thanks in advance for any help or suggestions.
John Pumphrey

Here is the client side: ( server side below client code)

Private Sub Form_Load()
    KeyPreview = True
    Winsock1.Protocol = sckTCPProtocol
    Winsock1.RemoteHost = "10.10.10.79"
    Winsock1.RemotePort = 100
    Winsock1.LocalPort = 100
End Sub

Private Sub PCMSend(Number$)
Dim DialString$
DialString$ = Number$
If Winsock1.State <> sckClosed Then Winsock1.Close
Winsock1.Connect "10.10.10.79", 100
Print "waiting for accept"
Do While Winsock1.State <> sckConnected
DoEvents
Loop
Print "accepted, sending data" + DialString$
Winsock1.SendData DialString$
Winsock1.Close
Print "sent, close socket"
End Sub

Here is the server side:

Private Sub Command1_Click()
Winsock1.LocalPort = 100
Winsock1.Listen
Print "socket should open"
If Winsock1.State = sckListening Then Print "socket open"
End Sub

Private Sub Winsock1_ConnectionRequest(ByVal requestID As Long)
If Winsock1.State <> sckClosed Then Winsock1.Close
Winsock1.Accept requestID
Print "accepted"
End Sub

Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
Print "data has arrived"
Dim strData As String
strData = String(bytesTotal, Chr$(0))
Winsock1.GetData strData, vbString, bytesTotal
Text1.Text = strData
End Sub
Avatar of Da_Weasel
Da_Weasel
Flag of United States of America image

First things first, port 100 should work, but to avoid possible future conflicts you should use a port number greater than 1024.
Now for the client side code:

Dim DialString as string

Private Sub Form_Load()
   KeyPreview = True
   Winsock1.Protocol = sckTCPProtocol
   Winsock1.RemoteHost = "10.10.10.79"
   Winsock1.RemotePort = 100
   Winsock1.LocalPort = 100
End Sub

Private Sub PCMSend(Number$)
   'make Dial String a global value
   DialString$ = Number$
   If Winsock1.State <> sckClosed Then Winsock1.Close
   Winsock1.Connect "10.10.10.79", 100
End Sub

Private Sub Winsock1_Connect()
   'Connection accepted so send data
   Print "accepted, sending data" + DialString$
   Winsock1.SendData DialString$
   Winsock1.Close
   Print "sent, close socket"
End Sub

Private Sub Winsock1_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)
   'an error occured so handle it
   Select Case Number
      Case sckHostNotFound
         msgbox "Could not find host"
      Case Else
         msgbox "Unhandled event!"
    End Select
End Sub

here is a complete list of the settings for the Number parameter

sckOutOfMemory 7 Out of memory
sckInvalidPropertyValue 380 The property value is invalid.
sckGetNotSupported 394 The property can't be read.
sckSetNotSupported 383 The property is read-only.
sckBadState 40006 Wrong protocol or connection state for the requested transaction or request.
sckInvalidArg 40014 The argument passed to a function was not in the correct format or in the specified range.
sckSuccess 40017 Successful.
sckUnsupported 40018 Unsupported variant type.
sckInvalidOp 40020 Invalid operation at current state
sckOutOfRange 40021 Argument is out of range.
sckWrongProtocol 40026 Wrong protocol for the requested transaction or request
sckOpCanceled 1004 The operation was canceled.
sckInvalidArgument 10014 The requested address is a broadcast address, but flag is not set.
sckWouldBlock 10035 Socket is non-blocking and the specified operation will block.
sckInProgress 10036 A blocking Winsock operation in progress.
sckAlreadyComplete 10037 The operation is completed. No blocking operation in progress
sckNotSocket 10038 The descriptor is not a socket.
sckMsgTooBig 10040 The datagram is too large to fit into the buffer and is truncated.
sckPortNotSupported 10043 The specified port is not supported.
sckAddressInUse 10048 Address in use.
sckAddressNotAvailable 10049 Address not available from the local machine.
sckNetworkSubsystemFailed 10050 Network subsystem failed.
sckNetworkUnreachable 10051 The network cannot be reached from this host at this time.
sckNetReset 10052 Connection has timed out when SO_KEEPALIVE is set.
sckConnectAborted 11053 Connection is aborted due to timeout or other failure.
sckConnectionReset 10054 The connection is reset by remote side.
sckNoBufferSpace 10055 No buffer space is available.
sckAlreadyConnected 10056 Socket is already connected.
sckNotConnected 10057 Socket is not connected.
sckSocketShutdown 10058 Socket has been shut down.
sckTimedout 10060 Socket has been shut down.
sckConnectionRefused 10061 Connection is forcefully rejected.
sckNotInitialized 10093 WinsockInit should be called first.
sckHostNotFound 11001 Authoritative answer: Host not found.
sckHostNotFoundTryAgain 11002 Non-Authoritative answer: Host not found.
sckNonRecoverableError 11003 Non-recoverable errors.
sckNoData 11004 Valid name, no data record of requested type
Avatar of John Pumphrey, Crestron CTI, DMC-E
John Pumphrey, Crestron CTI, DMC-E

ASKER

I tried your suggestion. It worked one time. Something I noticed last night was when the socket will not open a 2nd time. It will only open one time. Does W2000 pro handle winsock differently or is there a version specific to w2000?
Thanks for your help.
remove the line

Winsock1.Close

From the Winsock_Connect event and put it in the Winsock_SendComplete event
Thanks again weasel, it is getting closer. I can open the socket and send one time now. I added a button on the server to manually close the socket and then a second to re-open it. After sending one time I have to reboot the client machine. I moved the entire project to 2 different pc's to rule out local problems to each pc. I'm trying to specify the port number each time the socket is opened but it too gives the same result, send one time then reboot client. If the client is not rebooted the message box shows the unhandled event text when trying to send data.
Change the following

msgbox "Unhandled event!"

to this

msgbox "Error Number: " & Number

Then post the error number here...
the error that gets kicked back is 10048
paste the server code, sound like the server is holding on to the connection...
Here is the current server code.
You rock, thanks for all the help. Beer on me!



Option Explicit
Dim PhonoNumber As String
Dim PortOutput As Long
Dim PortInput As Long
Dim PhonoDirName As String
Dim InCall As Boolean
Dim SearchNumber As Long
Dim OutDigit1 As Integer
Dim OutDigit2 As Integer
Dim OutDigit3 As Integer
Dim LevelDigit1 As Integer
Dim LevelDigit2 As Integer
Dim LevelDigit3 As Integer
Dim ReceiverBuffer As String
Dim TestCaller As String
Dim TestCalled As String
Dim CallerOutDigit1 As Integer
Dim CallerOutDigit2 As Integer
Dim CallerOutDigit3 As Integer
Dim CallerLevelDigit1 As Integer
Dim CallerLevelDigit2 As Integer
Dim CallerLevelDigit3 As Integer
Dim CalledOutDigit1 As Integer
Dim CalledOutDigit2 As Integer
Dim CalledOutDigit3 As Integer
Dim CalledLevelDigit1 As Integer
Dim CalledLevelDigit2 As Integer
Dim CalledLevelDigit3 As Integer
Dim Called$
Dim CalledIndex As Long
Dim CallerID$
Dim CalledID$
Dim Hangup
Dim FName
Dim MyName
Dim AcceptCall
Dim PhonoIPAddress
Dim CallerSearch As Integer
Dim CalledSearch As Integer


Private Sub Command1_Click()
Winsock1.LocalPort = 2000
Winsock1.RemotePort = 2000
Winsock1.Listen

Print "socket should open"
If Winsock1.State = sckListening Then Print "socket open"
End Sub
Private Sub Command2_Click()
Winsock1.Close


End Sub

Private Sub Winsock1_ConnectionRequest(ByVal requestID As Long)

If Winsock1.State <> sckClosed Then Winsock1.Close

Winsock1.Accept requestID
Print "accepted"
Print requestID

End Sub

Private Sub txtSendData_Change()

'Winsock1.SendData txtSendData.Text
End Sub

Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
Print "data has arrived"
Dim strData As String
Winsock1.GetData strData$, vbString, bytesTotal
Text1.Text = strData

   ' Dim Number$, Caller$, CallerID$
   ' TestCaller = "Caller"
   ' TestCalled = "Called"
   ' Hangup = "hangup"
  '  AcceptCall = "accept"
   
    '    ReceiverBuffer = strData
     
   '    If Hangup = Left$(strData, 6) Then Call HangUpCall
       
     '  If TestCaller = Left$(strData, 6) Then Call ComputeCaller
     
     '  If TestCalled = Left$(strData, 6) Then Call ComputeCalled
   
     '  If AcceptCall = Left$(strData, 6) Then Call AcceptCaller

     
End Sub

Private Sub Winsock1_close()
Print "socket closed"
End Sub



Private Sub ComputeCaller()
'Print "entering compute caller"
CallerID$ = Right$(ReceiverBuffer, 4)
'ReceiverBuffer = ""
Open "c:\phonolist\numberlist.lst" For Input As #1
For SearchNumber = 1 To 16
Input #1, PhonoNumber$, OutDigit1, OutDigit2, OutDigit3, PhonoDirName$, PhonoIPAddress
If PhonoNumber$ = CallerID$ Then Call CallerInit
Next SearchNumber
Close #1
End Sub
Private Sub ComputeCalled()
Dim CalledID$, Searchbusy, CallerIDNumber$, CalledIDNumber$, CallNumber$, FName$, CallCount, IPnumber
CalledID$ = Right$(ReceiverBuffer, 4)
'ReceiverBuffer = ""
Open "c:\phonolist\numberlist.lst" For Input As #1
For SearchNumber = 1 To 16
Input #1, PhonoNumber$, OutDigit1, OutDigit2, OutDigit3, PhonoDirName$, PhonoIPAddress
If PhonoNumber$ = CalledID$ Then Call CalledInit
Next SearchNumber
'Loop
Close #1
'CompleteCalled:
   
End Sub
Private Sub HangUpCall()
Dim CallerID$, CalledID$, CallerIDNumber$, CalledIDNumber$, Fkill$, HUName, HUFname, Hangupreq$
Cls
Hangupreq$ = Right$(ReceiverBuffer, 4)

HUName = Dir("c:\PCMdata\*.dat")
HUFname = "c:\PCMdata\" + HUName
Do While HUName <> ""
Open HUFname For Input As #2
    Do While Not EOF(2)
    Input #2, CallerIDNumber$, CalledIDNumber$
   
    If Hangupreq$ = CallerIDNumber$ Then CalledID$ = CalledIDNumber$
    If Hangupreq$ = CallerIDNumber$ Then CallerID$ = CallerIDNumber$
    If Hangupreq$ = CalledIDNumber$ Then CallerID$ = CallerIDNumber$
    If Hangupreq$ = CalledIDNumber$ Then CalledID$ = CalledIDNumber$
       
    If CallerIDNumber$ = CallerID$ Then Fkill$ = HUFname
    If CalledIDNumber$ = CallerID$ Then Fkill$ = HUFname
    Loop
Close #2
HUName = Dir
Loop
   
Open "c:\phonolist\numberlist.lst" For Input As #1
For CallerSearch = 1 To 16
Input #1, PhonoNumber$, OutDigit1, OutDigit2, OutDigit3, PhonoDirName$, PhonoIPAddress
If PhonoNumber$ = CallerID$ Then Call CallerHungup
Next CallerSearch
Close #1

Call PesaCheckSum
Call ClearCallInfo

Open "c:\phonolist\numberlist.lst" For Input As #1
For CalledSearch = 1 To 16
Input #1, PhonoNumber$, OutDigit1, OutDigit2, OutDigit3, PhonoDirName$, PhonoIPAddress
If PhonoNumber$ = CalledID$ Then Call CalledHungup
Next CalledSearch
Close #1

Call PesaCheckSum
Call ClearCallInfo

On Error GoTo Backout
Kill Fkill$
Backout:
    Exit Sub
End Sub


Private Sub AcceptCaller()
Dim CalledID$, CallerID$, CallerIDNumber$, CalledIDNumber$, CalledName, CalledFName
CalledID$ = Right$(ReceiverBuffer, 4)
'ReceiverBuffer = ""
CalledName = Dir("c:\PCMdata\*.dat")
CalledFName = "c:\PCMdata\" + CalledName
Do While CalledName <> ""
Open CalledFName For Input As #3
    Do While Not EOF(3)
    Input #3, CallerIDNumber$, CalledIDNumber$
    If CalledIDNumber$ = CalledID$ Then CallerID$ = CallerIDNumber$
    Loop
Close #3
CalledName = Dir
Loop
Print CallerIDNumber$ + CalledIDNumber$

Open "c:\phonolist\numberlist.lst" For Input As #4
For SearchNumber = 1 To 16
Input #4, PhonoNumber$, OutDigit1, OutDigit2, OutDigit3, PhonoDirName$, PhonoIPAddress
If PhonoNumber$ = CallerID$ Then SearchNumber = 16
Next SearchNumber
'Loop
Close #4

CallerOutDigit1 = OutDigit1
CallerOutDigit2 = OutDigit2
CallerOutDigit3 = OutDigit3

Open "c:\phonolist\numberlist.lst" For Input As #4
For SearchNumber = 1 To 16
Input #4, PhonoNumber$, OutDigit1, OutDigit2, OutDigit3, PhonoDirName$, PhonoIPAddress
If PhonoNumber$ = CalledID$ Then SearchNumber = 16
Next SearchNumber
'Loop
Close #4

LevelDigit1 = OutDigit1
LevelDigit2 = OutDigit2
LevelDigit3 = OutDigit3
Call CompleteCall
'Call ClearCallInfo
End Sub


Private Sub CallerInit()
SearchNumber = 16
Close #1
CallerOutDigit1 = OutDigit1
CallerOutDigit2 = OutDigit2
CallerOutDigit3 = OutDigit3
CallerLevelDigit1 = OutDigit1
CallerLevelDigit2 = OutDigit2
CallerLevelDigit3 = OutDigit3
'Print CallerOutDigit1
'Print CallerOutDigit2
'Print CallerOutDigit3
Call StartCall

End Sub
Private Sub CalledInit()
SearchNumber = 16
Close #1
CalledOutDigit1 = OutDigit1
CalledOutDigit2 = OutDigit2
CalledOutDigit3 = OutDigit3
CalledLevelDigit1 = OutDigit1
CalledLevelDigit2 = OutDigit2
CalledLevelDigit3 = OutDigit3
'Print CalledOutDigit1
'Print CalledOutDigit2
'Print CalledOutDigit3
'Call StartCall
'Call CompleteCall
End Sub

Private Sub StartCall()
OutDigit1 = CalledOutDigit1
OutDigit2 = CalledOutDigit2
OutDigit3 = CalledOutDigit3
LevelDigit1 = CallerLevelDigit1
LevelDigit2 = CallerLevelDigit2
LevelDigit3 = CallerLevelDigit3
Call PesaCheckSum
Call ClearCallInfo
End Sub
Private Sub CompleteCall()
SearchNumber = 16
Close #4
OutDigit1 = CallerOutDigit1
OutDigit2 = CallerOutDigit2
OutDigit3 = CallerOutDigit3
LevelDigit1 = CalledLevelDigit1
LevelDigit2 = CalledLevelDigit2
LevelDigit3 = CalledLevelDigit3
Call PesaCheckSum
Call ClearCallInfo
End Sub

Private Sub PesaCheckSum()
Print "Sending Pesa Commands"
Dim HigherSumOutput As String
Dim LowerSumOutput As String
Dim PreCheckSum As Integer
Dim CheckSum As Byte
Dim LowerSum As Byte
Dim UpperSum As Byte
Dim Number$
PreCheckSum = 72 + Asc(OutDigit1) + Asc(OutDigit2) + Asc(OutDigit3) + Asc(LevelDigit1) + Asc(LevelDigit2) + Asc(LevelDigit3)
CheckSum = 255 And PreCheckSum
UpperSum = CheckSum \ 16
LowerSum = 15 And CheckSum
HigherSumOutput = Chr(UpperSum + 48)
LowerSumOutput = Chr(LowerSum + 48)
Number$ = "H" + CStr(OutDigit1) + CStr(OutDigit2) + CStr(OutDigit3) + CStr(LevelDigit1) + CStr(LevelDigit2) + CStr(LevelDigit3) + CStr(HigherSumOutput) + CStr(LowerSumOutput) + vbCrLf
Print Number$
Dial Number$

End Sub


Private Sub Dial(Number$)
    Dim DialString$
    DialString$ = vbCrLf + Number$
    MSComm1.CommPort = 1
    MSComm1.Settings = "9600,N,8,2"
    MSComm1.Handshaking = 0
   On Error Resume Next
    MSComm1.PortOpen = True
    MSComm1.InBufferCount = 0
    MSComm1.Output = DialString$
    MSComm1.PortOpen = False
    Number$ = ""
    DialString = ""
End Sub

Public Function ClearCallInfo()
CalledOutDigit1 = 0
CalledOutDigit2 = 0
CalledOutDigit3 = 0
CalledLevelDigit1 = 0
CalledLevelDigit2 = 0
CalledLevelDigit3 = 0
CallerOutDigit1 = 0
CallerOutDigit2 = 0
CallerOutDigit3 = 0
CallerLevelDigit1 = 0
CallerLevelDigit2 = 0
CallerLevelDigit3 = 0
CallerID$ = ""
CalledID$ = ""
End Function

Public Function CallerHungup()
CallerSearch = 16
Close #1
LevelDigit1 = OutDigit1
LevelDigit2 = OutDigit2
LevelDigit3 = OutDigit3

End Function

Public Function CalledHungup()
CalledSearch = 16
Close #1
LevelDigit1 = OutDigit1
LevelDigit2 = OutDigit2
LevelDigit3 = OutDigit3

End Function
inside your Winsock1_DataArrival you need a Winsock1.Close at the end to close the port after the data is recieved

Im about to head home, so i might not reply for another hour or so...maybe not till tomorrow (EST)
I added the line to my dataArrival event and I still have the same problem. I tried shutting down the server app just to see if I would get a hostnotfound error but instead I get the same 10048 error. I added a button to the client to manually close the socket and a winsock_close event line to print a indication that the socket closed. After sending data the winsock_close event would not fire and after pressing the button it would not fire. It seems the client isn't closing the socket. After a few beers and a lot of thought the only thing I can think that is the same between the two sets of pc's used for the client is they both have two nics'. Should I use the bind method? From what I read it is for multiple ip addresses or do I need to specify the local ip? only one nic is being used.
I added the socket closed verification to both server and client, both are verifying the socket is closing. So I was wrong about the client keeping the socket open. The error pertains to the address being in use, should I pass the connect request to a new instace of the winsock? Not sure exactly on how to do this, I've been reading tons of stuff since 4:00 this morning and found a few examples but I don't fully understand how it is supposed to be used.
jpumpster:
This old question needs to be finalized -- accept an answer, split points, or get a refund.  For information on your options, please click here-> http:/help/closing.jsp#1 
Experts: Post your closing recommendations!  Who deserves points here?
Avatar of DanRollins
jpumpster, an EE Moderator will handle this for you.
Moderator, my recommended disposition is:

    Refund points and save as a 0-pt PAQ.

DanRollins -- EE database cleanup volunteer
*5 months later*

lol, sorry
wow, forgot all about this one....
If you are still playing with this, you can try running netstat on each computer after the problem begins to see if there is a open connection to port 2000 on either machine.....if so then the connection is not begin released...
ASKER CERTIFIED SOLUTION
Avatar of Computer101
Computer101
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial