Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

winsock can receive messages, but can't send....

Status
Not open for further replies.

OrthoDocSoft

Programmer
May 7, 2004
291
US
Folks,

Some of you may remember that I've written my own HL7 "listener" using the winsock object. This works partially, in that I can receive messages (and am doing so), but when I try to send acknowledgement replies, the app that is sending them isn't receiving them. This may be backwards, but I'm calling myself the "server" and the source of the HL7 messages the "client."

He tells me to "listen" on port "1234". I enter this in a textbox, and then fire up this code:

Code:
Private Sub cmdStartServer_Click()

On Error GoTo ErrorHandler

If Not IsNumeric(txtLocalPort.Text) Then
    
    txtLocalPort.Text = 0
    
End If

'If one Copy of Our Application is already running then don't load a new one
If Not App.PrevInstance = True Then

    'This can be any Valid Port Number
    Winsock1.LocalPort = CLng(txtLocalPort.Text)

    'Wait for Clients to Connect with Your Server.
    
    MsgBox "Your selected local port is " & Winsock1.LocalPort
    
    Winsock1.Listen

End If

Exit Sub

Under the Winsock1.DataArrival, I have this:

Code:
Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)

'MsgBox "data arrived"

Static X As Long

'Count how many times you execute this code.
X = X + 1

If X > 1000000 Then X = 0

lblCount.Caption = "Total messages arrived = " & X

On Error Resume Next

Winsock1.GetData strIncomingMessageG, vbString

Call DissectMessageForFiling(strIncomingMessageG)

Call SendAcknowledgment(strIncomingMessageG)

End Sub

DissectMessageForFiling works fine.

SendAcknowledgment essentially looks like this:

Code:
.....

'build a string
strCompleteACKMessage = strMSHSegment & strMSASegment

Winsock1.SendData strCompleteACKMessage

But my "client" doesn't receive it.

Can anyone see the problem?

Thanks,

Ortho

[lookaround] "you cain't fix 'stupid'...
 
Not too sure but I think you need to identify the port and IP of the remote computer.

[gray]Experience is something you don't get until just after you need it.[/gray]
 
Any given DataArrival doesn't occur for a "message" but whenever there are 1 to n bytes available to receive. If the computers are relatively fast and idle and the network relatively fast it may appear to get whole messages individually - then fail in the real world. You need to accumulate received data and parse out messages based on your protocol's framing.

You might get 1 byte, half a message, 2 messages, 3 1/2 messages etc. If your protocol is slow and chatty (ack requried before a new message is sent) you'll never have more than 1 message but you may well only get the one in bits and pieces.

I don't think that's your problem here though.

You send logic looks fine as far as it goes. We can't see much here though.

Are you sending all of the required message framing? Perhaps the client is getting data but not everything it needs to identify and isolate whole messages?


Otherwise the only thing left is to ask if you are at VB6 SP6. Lots of small bugs were fixed in the Winsock control over the years. Sadly some of the recent "security rollup" releases for VB6 controls broke the Winsock control in various ways too. Hopefully you resisted installing those (late 2008 to present). There was no option to uninstall them via Add/Remove Programs.
 
I used to do this, it required a handshake front end.

I used to send an ack, and stuff... I remember "chunks"

Lemme look into it... been a while, but once I have it one way, it worked both, you may want to make sure your firewall or port forwarding in the router isn't killing it.

btw, you can use any port, but you might be conflicting with some port for software on your machine. Look up "Well known ports". My stuff worked to 32434. I probably could have gone higher.(65?) I found out once I was conflicting with Warcraft III. Would'a thunk it?

Back in the day, NT-4, I wrote an app that worked great for a few weeks, and then just died. It was like NT was tired of me playing on any port, and no one ever had an answer.

It would work peer to peer, but NT just said no. That was corrected years later, and I've written stuff later that worked great.

I was doing stuff like send on one port, recv on another. Sending text commands to the receiver, and executing.

I'll look through the old code.
 
the Server is the machine with "listen" running. that's the only diff. Once you're connected, it makes no diff, who's who.

I used it on a LAN, but built it with the same machine, and you had to compile and run the other, then connect with the IDE version of the other, on the same machine. when i was fixing the server, I'd compile and run the client, then just run the server in IDE, switch to the compiled client push a button. Switch back and fix the breakpoint.

Pain in the butt to remember which you had running compiled.

I used 127.0.0.1 as the connect addy. Or localhost, can't remember.

:)
 
Dilettante,

I think I understand what you are saying about "messages" versus "1 to n bytes" but that does not seem to be my problem. The app that is "serving" the messages seems to send them in "complete messages." I've received probably millions of messages, have stored over 60,000 messages (or the data I want from them) in my DB, and that part is working just fine. But I appreciate what you are saying, and if it becomes a problem, I'll talk to you again.

Are you sending all of the required message framing?

By that, do you mean from a "VB6" standpoint or from a "message" standpoint? I think you mean the latter.

I'll check more closely into that; you are onto something there. Maybe a carriage return-line feed, or symbol that needs to be somewhere in the message for the software receiving my ack messages to "recognize" them. From a VB6 standpoint, the code you see is what I'm doing. Period.

Are you in SP6?

Yes, Thanks.

DocJohn,

My HL7 guy assures me that within our intranet, there is no firewall issue. I will check with my hardware guy about "port forwarding."

About the port I'm listening on, it is "7228" and was given to me by the HL7 guy who is sending the data. I insert this as a long value into with: Winsock1.LocalPort = 7228. We are "hooking up" as evidenced by the volumes of data I've allluded to above. He just can't get my ack return messages.

Perhaps we should try some different ports? I'll try that.

And your later post seems to talk about debugging the server against the client using 127.0.0.1, which I do at home and it works just fine.

Appreciate you guys help. PLEASE stick with me as I post the results of what I've done. REALLY appreciate your help.

[lookaround] "you cain't fix 'stupid'...
 
Just to be certain, have you tried putting a DoEvents after your Winsock1.SendData strCompleteACKMessage?

 
As far as I can get from the truly awful documentation I can find, HL7 MLLP messages need framing as in:

[tt]<VT>message body<FS><CR>[/tt]

In some cases the [tt]<CR>[/tt] is optional, but typically it is required.

This also applies to ACK/NAK:

[tt]<VT><ACK><FS><CR>[/tt]

That's separate from application level acks, which are application messages, typically replies rather than acks (but the docs are awful).

The characters shown in < > above are the ASCII control character mnemonics.

It also appears that there should never be LFs involved, even in the message body text.


You're probably already doing all of that though.

I'm not sure what your thinking is re. [tt]DoEvents()[/tt] calls there strongm. That's usually deadly in Winsock programming due to re-entrancy.
 
Oh I wouldn't normally advise its use anywhere if it can be helped, as you are aware. I'm just exploring some possibilities here though.
 
Ah, well I just thought you spotted something there in the code that was eluding me.


Without more information I'm still leaning toward the idea that the "other end" is waiting for start/end framing sequences and not getting what it needs to proceed.
'build a string
strCompleteACKMessage = strMSHSegment & strMSASegment
Winsock1.SendData strCompleteACKMessage
What is in those String variables? By their names I'd tend to assume the framing sequences are not in them.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top