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 Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

TCP/IP Messaging 1

Status
Not open for further replies.

JimHorton

Programmer
Jan 29, 2000
991
0
0
US
Hi all,
What is the best way to send data messages over a tcpip network? I guess I'm looking for something like AOL's IM, but without the screens. I'd have an Informix db on AIX and about 200 PC's with win98 on a WAN. Upon update of certain informix tables, a db trigger would fire, which would send over tcpip a simele text message with a record ID and some of the data from that updated record. It wouldn't go to all pc's, but just ones that the trigger logic decides need this data--so it wouldn't be a broadcast. The clients need to have this message within 5 seconds of it's update.

So the trigger fires, and it sees that this record's updated data needs to go to, say, 15 ip addresses, (which are in an informix table), and then it sends the message, and a VB program running on the PC clients would need to get this message and then deal with the data.

The current ad-hoc solution is to have the clients poll the server over a wan. You can see that 200 clients hitting this box every 5 seconds to do an index scan and possibly a fetch is going to be a burden, not to mention wan traffic bottlenecks.

So 'push' is the way I want to go, but I'm not sure how to accomplish this.
Thanks for any ideas,
-Jim
 
I would suggest that you use a UDP message to 'push' the update, because you don't have to go through the handshake process.

If I were writing this, I would have each PC set up a TCP connection to the server when the client application is run, effectively registering its IP address with the server. That way, when you switch to dhcp, it won't matter to your application.

I would have a periodic (maybe every 5 minutes) TCP transaction take place so that a client which becomes disconnected (through some unrecoverable method) will be removed from potential future updates.

Then I would send the update requests as UDP packets because they do not require handshaking, and if they drop, so be it. Another one may be coming in the next 5 seconds, so it isn't worth the time to attempt to recover the packet.

I might even include the number of updates that have been sent in the TCP handshake so that you can determine the quality of service that you are providing by comparing that to the number of updates actually received.

Of course this is probably not very NAT friendly, but there may be a way to do that, I'd just have to think about it for a while.

pansophic
 
pansophic,
Thank you for replying. I'm new to this, and I'm not able to get the machines to speak to one another. I've looked at the winsock api reference, and took some sample VB code using the winsock api. I'm able to sucessfully use the connect, send, and recieve methods (by 'successfully', I mean no runtime error occurs, the function returns a sucess code), but the recieve method doesn't return any data. I set up this sample form up on both machines, passed the correct local/remote ip's for each machine, but a recieve() on machine b recieves nothing after a send() on machine a.

Also, the port I pass to winsock does return an error if it's zero (yet the docs said this is fine--winsock will just assign an unused one), it only works when I pass an already open port--4899--which is the port for the vnc remote viewer which I'm using to work on the remote machine. There is a listen() function in the winsock api that this sample code does not use, I'm wondering if that's what might be missing.

If you could give me some pseudo code for some basic transfer of data between 2 machines using winsock (either tcp or udp), that would be great. I'm not asking anyone to write my code for me, just a nudge in the right direction. Thanks,
--Jim
 
Jim,

You are on the right track. The computer that is acting as the server needs to 'listen' on a fixed port (you define the number, but try to stay away from commonly used ports unless there is a reason to use it). There is an event that occurs when someone attempts to connect to you. When that event occurs, you want to 'Load Winsock1(x)' to establish a new winsock to communicate with. If you do not, then you can only ever have one connection up at a time. x needs to be an integer array pointer.

On the client computer, the one that is opening the connection, is where you want to use the port 0, so that it will open the next available ephemeral port (1024-5000). If you fix the source port for the connection, you may run into issues with conflicts (multiple applications vying for the same port).

I'm including some of the critical sample code from Visual Basic 6 Unleashed by Rob Thayer, et. al. published by SAMS:

Client side:

Private Sub cmdConnect_Click()
Winsock1.RemoteHost = "127.0.0.1"
Winsock1.RemotePort = 1007
Winsock1.Connect
End Sub

Private Sub cmdSend_Click()
If Winsock1.State = sckConnected Then
Winsock1.SendData txtItem.Text
lblMessage.Caption = "Sending Data"
Else
lblMessage.Caption = "Not currently connected to host"
End If
End Sub

Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
Dim sData As String

Winsock1.GetData sData, vbString
lblPrice.Caption = sData
End Sub

Server side:

Option Explicit
Dim iSockets As Integer
Dim sServerMsg As String
Dim sRequestID As String

Private Sub Form_Load()
'------------------------------------------------------------------^M
' Program : Server2.exe
' Author: Loren D.Eidahl
' Noticce:
'
'------------------------------------------------------------------^M
frmServer.Show
lblHostID.Caption = Socket(0).LocalHostName
lblAddress.Caption = Socket(0).LocalIP
Socket(0).LocalPort = 1007
sServerMsg = "Listening to port: " & Socket(0).LocalPort
List1.AddItem (sServerMsg)
Socket(0).Listen
End Sub

Private Sub socket_Close(Index As Integer)
sServerMsg = "Connection closed: " & Socket(Index).RemoteHostIP
List1.AddItem (sServerMsg)
Socket(Index).Close
Unload Socket(Index)
iSockets = iSockets - 1
lblConnections.Caption = iSockets

End Sub

Private Sub socket_ConnectionRequest(Index As Integer, ByVal requestID As Long)
sServerMsg = "Connection request id " _
& requestID & " from " & Socket(Index).RemoteHostIP
If Index = 0 Then
List1.AddItem (sServerMsg)
sRequestID = requestID
iSockets = iSockets + 1
lblConnections.Caption = iSockets
Load Socket(iSockets)
Socket(iSockets).LocalPort = 1007
Socket(iSockets).Accept requestID
End If
End Sub

Private Sub socket_DataArrival(Index As Integer, ByVal bytesTotal As Long)
Dim sItemData As String
Dim strData As String
Dim strOutData As String

' get data from client
Socket(Index).GetData vtData, vbString
sServerMsg = "Received: " & vtData & " from " & _
Socket(Index).RemoteHostIP & "(" & sRequestID & ")"
List1.AddItem (sServerMsg)

' Get clients request from database
strData = "ItemNumber = '" & sItemData & "'"
Data1.Recordset.MoveLast
Data1.Recordset.FindFirst strData
strOutData = Data1.Recordset.Fields("Price")

'send data to client
sServerMsg = "Sending: " & strOutData & " to " &
[ic:ccc] Socket(Index).RemoteHostIP
List1.AddItem (sServerMsg)
Socket(Index).SendData strOutData

End Sub

pansophic
 
pansophic,
Thank you...that worked! I guess using the winsock control is what did it, my use of raw api calls must have missed something, but I'll go back and check that out and see if I can get my api method working--for academic reasons. Do you know offhand if, within the AIX world, I would be stuck with that os's sockets api, or is there the equivalent of a built-in control, say, for C++ in the aix environment?
--Jim
 
Don't know for sure off-hand, but I have used things like Net::RawIP, which is a Perl library for handling raw sockets. I've also used libnet and libpcap, which are C libraries for communicating over the net.

There are lots of libraries out there that simplify things like ftp, smtp, etc. Look out on Sourceforge and CPAN if you know Perl. You may find it easier than programming from scratch. I generally just find someone else's code that is close to what I need and modify it to do what I want. I'm not really a programmer.

Also, all of my *nix programming experience comes from Linux, so it may not be directly portable to the AIX environment.

pansophic
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top