Tsocket

Post Reply
User avatar
reinaldocrespo
Posts: 918
Joined: Thu Nov 17, 2005 5:49 pm
Location: Fort Lauderdale, FL

Tsocket

Post 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.
User avatar
James Bott
Posts: 4654
Joined: Fri Nov 18, 2005 4:52 pm
Location: San Diego, California, USA
Contact:

Post 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
User avatar
reinaldocrespo
Posts: 918
Joined: Thu Nov 17, 2005 5:49 pm
Location: Fort Lauderdale, FL

Post 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
User avatar
James Bott
Posts: 4654
Joined: Fri Nov 18, 2005 4:52 pm
Location: San Diego, California, USA
Contact:

Post 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
User avatar
reinaldocrespo
Posts: 918
Joined: Thu Nov 17, 2005 5:49 pm
Location: Fort Lauderdale, FL

Post 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.
User avatar
reinaldocrespo
Posts: 918
Joined: Thu Nov 17, 2005 5:49 pm
Location: Fort Lauderdale, FL

Post 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
User avatar
eduardofreni
Posts: 12
Joined: Sat Aug 26, 2006 12:27 am
Location: Florence (Italy)

reinaldo a good ip monitor give us a gread hand.

Post 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
User avatar
reinaldocrespo
Posts: 918
Joined: Thu Nov 17, 2005 5:49 pm
Location: Fort Lauderdale, FL

Post by reinaldocrespo »

Eduardo;

Thank you. I will try it.

Reinaldo.
User avatar
James Bott
Posts: 4654
Joined: Fri Nov 18, 2005 4:52 pm
Location: San Diego, California, USA
Contact:

Post 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
User avatar
reinaldocrespo
Posts: 918
Joined: Thu Nov 17, 2005 5:49 pm
Location: Fort Lauderdale, FL

Post 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.
User avatar
AlexSchaft
Posts: 172
Joined: Fri Oct 07, 2005 1:29 pm
Location: Edenvale, Gauteng, South Africa

Sockets

Post 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
Post Reply