Page 1 of 1
Tsocket
Posted: Tue Aug 29, 2006 5:25 pm
by reinaldocrespo
Hi,
For some reason when trying to create a socket connection to a given port on at a given IP, the socket gets created at the local computer's ip instead. Here is my code:
Code: Select all
oSocket := TSocket():New( 15000 )
osocket:lDebug := .t.
oSocket:cLogfile := cFilePath( GetModuleFileName( GetInstance() ) ) + "trace.log"
oSocket:bRead = { | oSocket | aadd( m->aAcks, oSocket:GetData() ) }
oSocket:bConnect = { || logfile( "trace.log", { "Connected to ip:"+osocket:cIpAddr } ) }
oSocket:Connect( "98.19.1.4" )
Here I'm trying to connec to a local server at ip 98.19.1.4 which is listening on port 15000. But when I look at the trace.log file I find it is connecting to ip 98.19.1.187 which is the local computer's ip and not to the desired ip, thus any send/receive data attemp fails.
Any Ideas why?
The funny thing is that yesterday it was connecting to the right ip and I got to send and receive data just perfectly. I know as a matter of fact that the server is listening at 15000 and that the server's ip is correct.
I'm using xharbour 0.99.61 w/FW2.7 + BCC 5.5.
Reinaldo.
Posted: Tue Aug 29, 2006 5:35 pm
by James Bott
Hi Rienaldo,
I have not done much work with sockets, but I know that when strange things are happening that don't seem to make sense (with any code), sometimes adding a sysRefresh() fixes the problem. It's worth a try. I would put it just before the connect.
James
Posted: Tue Aug 29, 2006 8:16 pm
by reinaldocrespo
James;
Thank you for your reply. I inserted sysfresh(). Still same behavior.
Listen, anyone can try this even without a socket server working listening. If you try to connect to non existent IP it connects to your own ip even if no service is listening on the specified port.
Try using my very same example above. You'll get connection or so is tsocket's behavior although no real connection exists.
Reinaldo
Posted: Tue Aug 29, 2006 8:31 pm
by James Bott
Reinaldo,
I tried running it here and it hung at this line:
oSocket:bRead ...
I commented out that line and it runs through all the rest of the lines but I get no trace.log so it seems I am NOT getting a connection. I also disabled my firewall but there was no change.
James
Posted: Tue Aug 29, 2006 8:41 pm
by reinaldocrespo
James;
Check again. Sometimes it takes a few seconds for the trace.log file to create and have info on it.
I'm testing it here on my own computer where I have no access to private ip 98.19.1.4, and I do get a trace file. It reads : Connected to ip:192.168.1.2.
The line osocket:bRead := ... is just assigning a code block to a variable. I wonder why would it hang....? Makes no sense to me.
Check again your app directory for trace.log.
Posted: Tue Aug 29, 2006 9:19 pm
by reinaldocrespo
Here is a self contained sample:
compile and execute. After 30 seconds check your app's dir. You'll find a trace.log file and an actual connection where you can click on send and no error is reported. Futhermore, Tsocket reports being connected to your local computer's ip instead of the assigned ip.
Unless I'm missing something here, this self contained sample proves how tsocket is not working properly???
Code: Select all
#include "Fivewin.ch"
FUNCTION MAIN()
LOCAL oWnd
local oMsg
DEFINE WINDOW oWnd
@ 1, 2 BUTTON "Send";
SIZE 100, 50;
ACTION ( oMsg:CreateHL7Message(), ;
oMsg:Tcp_HL7_Transmit(), ;
omsg:IsAcknowledged() )
ACTIVATE WINDOW oWnd ;
ON INIT ( oMsg := tExporter():new(), omsg:SetupIPSocket() ) ;
VALID( omsg:end(), .t. )
RETURN NIL
*-------------------------------------------------------------------------------------------------------------------------------
CLASS TEXPORTER
DATA oSocket
DATA isConnected AS LOGIC INIT .f.
DATA nPort AS NUMERIC INIT 15000
DATA cIp, cId, cHL7
DATA aAcks AS ARRAY INIT {}
METHOD New() CONSTRUCTOR
METHOD SetupIpSocket()
METHOD Tcp_Hl7_Transmit()
METHOD isAcknowledged()
METHOD CreateHL7Message()
METHOD UniqueId() // HL7 segments
METHOD obx()
METHOD obr()
METHOD orc()
METHOD Pid()
METHOD Env()
METHOD Msh()
METHOD nte()
METHOD End()
END CLASS
*-------------------------------------------------------------------------------------------------------------------------------
METHOD new() CLASS TEXPORTER
::nPort := 15000
::cIP := "98.19.1.4"
RETURN SELF
*-------------------------------------------------------------------------------------------------------------------------------
METHOD SetupIpSocket() CLASS TEXPORTER
::oSocket := TSocket():New( ::nport )
::osocket:lDebug := .t.
::oSocket:cLogfile := cFilePath( GetModuleFileName( GetInstance() ) ) + "trace.log"
::oSocket:bRead = { | oSocket | aadd( ::aAcks, oSocket:GetData() ) }
::oSocket:bConnect = { || ::isConnected := .t., logfile( "trace.log", { "Connected to ip:", ::osocket:cIpAddr } ) }
::oSocket:Connect( ::cIp )
RETURN NIL
RETURN NIL
*-------------------------------------------------------------------------------------------------------------------------------
METHOD CreateHL7Message() CLASS TEXPORTER
::uniqueId()
::cHL7 := chr( 11 ) + ::msh() + chr(13) + ;
::env() + chr( 13 ) + ;
::pid() + chr( 13 ) + ;
::orc() + chr( 13 ) + ;
::obr() + chr( 13 ) + ;
::obx() + chr( 13 ) + ;
/*::nte() + chr( 13 ) +*/ chr( 28 ) + chr( 13 )
RETURN NIL
*-------------------------------------------------------------------------------------------------------------------------------
METHOD Tcp_HL7_Transmit() CLASS TEXPORTER
if !::isConnected
MsgStop( "Connection to " + ::oSocket:cIpAddr + " at " + cValToChar( ::osocket:nPort ) + " failed." )
Return Nil
Endif
::oSocket:SendData( ::cHL7 )
RETURN NIL
*-------------------------------------------------------------------------------------------------------------------------------
METHOD isAcknowledged() CLASS TEXPORTER
local aParsed
local nPos
if !empty( ::aAcks )
aParsed := HB_ATOKENS( aTail( ::aAcks ), chr( 13 ), .T., .F.)
nPos := aScan( aParsed, { |e| left( e, 3 ) == "MSA" } )
if nPos > 0
aParsed := HB_ATOKENS( aParsed[ nPos ], "|", .T., .F. )
if alltrim( aParsed[ 3 ] ) == alltrim( ::cId ) .and. "NORMAL" $ upper( aParsed[ 4 ] )
RETURN .T.
Endif
endif
Endif
RETURN .F.
*-------------------------------------------------------------------------------------------------------------------------------
METHOD Msh() CLASS TEXPORTER
local cStr := "MSH|"
cStr += "^~\&|" //2- encoding chars
cStr += "MP8-PathLabs|" //3- snd app
cStr += "|" //4- snd facility
cStr += "|" //5- recv app
cStr += "|" //6- recv facility
cstr += DTOS( date() ) + StrTran( time(), ":", "" )+ "|" //7
cStr += "|" //8
cstr += "ORU^R01|" //9
cstr += ::cId + "|" //10
cStr += "||||"
RETURN cStr
*-------------------------------------------------------------------------------------------------------------------------------
METHOD Env( cTrigger ) CLASS TEXPORTER
local cStr := "EVN|"
cStr += "R01|"
cStr += DTOS( date() ) + StrTran( time(), ":", "" ) + "|"
RETURN cStr
*-------------------------------------------------------------------------------------------------------------------------------
METHOD Pid() CLASS TEXPORTER
local cStr := "PID|"
cStr += "||"
cStr += "REC:00000001|"
cStr += "||||||||||||||"
cStr += "ACC:00000001^^^^^|"
cStr += "|"
RETURN cStr
*-------------------------------------------------------------------------------------------------------------------------------
METHOD orc() CLASS TEXPORTER
local cStr := "ORC|"
cStr += "RE|"
cStr += "ORDER:0000000^|"
cStr += "|||||||"
cStr += "USERID|"
cStr += "|||||||||"
RETURN cStr
*-------------------------------------------------------------------------------------------------------------------------------
METHOD obr() CLASS TEXPORTER
local cStr := "OBR|"
cStr += "ORDER:0000001^|"
cStr += "|||||"
cStr += DTOS( Date() ) + StrTran( Time(), ":", "" ) + "|"
cStr += "||"
cStr += "TRNSCRIPT|"
cStr += "||||||||||||||"
cStr += "F|"
cStr += "||||||"
cStr += "PTHLGST^PthlgstNameString|"
cStr += "|||||||||||"
RETURN cStr
*-------------------------------------------------------------------------------------------------------------------------------
METHOD obx() CLASS TEXPORTER
local cStr := ""
local nSeq
//local aRsts :={ ::oTrans:oTrGrss:GetText(), ::oTrans:oTrDg:GetText() }
local aRsts := { "Text line one. Sample text. The fox jumped over the white fence", ;
"Text line two. Sample text. More foxes jumped over the white fence" }
For nSeq := 1 to 2
cStr += "OBX|"
cStr += cValToChar( nSeq )+ "|"
cStr += "ST|"
cStr += "||"
cStr += aRsts[ nSeq ] +"|"
cStr += "||||||||||||" + chr(13)
Next nSeq
RETURN cStr
*-------------------------------------------------------------------------------------------------------------------------------
METHOD Nte() CLASS TEXPORTER
local cStr := "NTE|"
RETURN cStr
*-------------------------------------------------------------------------------------------------------------------------------
METHOD UniqueId() CLASS TEXPORTER
local cPrvId := ::cId
While ::cId == cPrvId
::cid := Right( cValToChar( Year(date() ) ), 2 ) + ;
StrZero( Month( date() ),2 ) + ;
StrZero( Day( date() ),2 ) + ;
cValToChar( Seconds() )
End
return nil
*-------------------------------------------------------------------------------------------------------------------------------
METHOD End() CLASS TEXPORTER
iif( upper( valtype( ::osocket ) ) == "O", ::osocket:End(), )
RETURN NIL
reinaldo a good ip monitor give us a gread hand.
Posted: Tue Aug 29, 2006 10:06 pm
by eduardofreni
I worked with socket.
My FiveWin WebServer, have 4 years of work and give me 0 problems. All maked with fivewin class with few modify.
I am satisfied from this tecnology in Fivewin.
But prior of write a software for network, you have installed a network monitor?.
Else, in some case, you not succeed to find the problem, and you do not succeed to see how the net works.
Even if studies 100 books of tcpip, not are nothing better than an IP monitor.
You may be to see the network trafic in and out of your computer, the dialog with the server ecc ecc.
I try the ip monitor at
http://www.networkactiv.com/
I use it from 3 year.
Test it you can resolve many problem.
Best Regards
Eduardo Freni
Posted: Wed Aug 30, 2006 12:12 am
by reinaldocrespo
Eduardo;
Thank you. I will try it.
Reinaldo.
Posted: Wed Aug 30, 2006 1:10 am
by James Bott
Reinaldo,
OK, I guess I just didn't wait 30 seconds. I tried again and waited longer (my original code). I found the trace.log and I also looked at my firewall log. Here are the results:
Trace Log
08/29/06 17:59:22: Connect Socket handle: 1892
08/29/06 17:59:22: Connected to ip:192.168.0.101
---------------
Symantec Personal Firewall log
Connection: 192.168.0.102: 4095.
to MATRIX(192.168.0.101): netbios-ssn(139).
4 bytes sent.
660 bytes received.
3.144 elapsed time.
It seems that the firewall claims my computer "Matrix IP address 192.168.0.101) connected to itself, however, the firewall log says it created a new address 192.168.0.102. I don't know if this info is of any help.
James
Posted: Wed Aug 30, 2006 1:45 am
by reinaldocrespo
James;
Thank you for the reply.
Regarding sockets, there seems to be more than what meets the eye or the obvious. Indeed you do have a socket connection. Although no real communication will ever occur, the socket client is up and "working".
I've had to just disregard, for now, certainty of a true connection to a listening port and proceed by faith with data sends and expect replys. If no acknoledgement is received with the expected acceptance message, then simply display an error message to alert the user. Interestingly enough I do get the expected answers from 98.19.1.4 although Tsocket:cipAddr contains the ip of the client computer where my app is running instead of the expected 98.19.1.4.
Perhaps I'm the last to find out that the notion of sockets is a very interesting subject at the very least. Think of the capabilities. You can actually have instruments (hardware) and different pieces of software speaking to each other. You could have a tsocket server listening on your client's server for messages from your own software to perform... the possibilities are endless. AMOF, no more RS232.
At this very moment I'm uploading pathological transcriptions results up to a main frame where doctors can connect to and view clinical histories of patients. At this moment I'm not totally happy with the way it is working for the reasons I explained above. But it is working nevertheless.
Reinaldo.
Sockets
Posted: Wed Aug 30, 2006 3:45 am
by AlexSchaft
Hi,
One thing I found is that when the connection doesn't connect, the connect event still fires, but oSocket:ClientIP() returns "0.0.0.0"
oSocket:cIPAddr is always your own address, as set by
::cIPAddr = GetHostByName( GetHostName() )
in the new method.
HTH's
Alex