Operating System - OpenVMS
cancel
Showing results for 
Search instead for 
Did you mean: 

Fortran TCP/IP Programming Examples?

 
SOLVED
Go to solution
Darlene Riddle
Occasional Visitor

Fortran TCP/IP Programming Examples?

I found a Fortran TCP/IP example in an "Ask the Wizard" from July 1999. Using that example I am trying to store an IP address into a sin$l_addr. If I store a value greater than 127 in the fourth octet (see D in the example) I get an integer overflow error. My operating system is OpenVMS 8.3-1H1 and the compiler is FORTRAN V8.0-1.
7 REPLIES 7
Hein van den Heuvel
Honored Contributor

Re: Fortran TCP/IP Programming Examples?



Ah, I see.

You are using the example from

http://h71000.www7.hp.com/wizard/wiz_2777.html

And it is probably dying on the clumsy sign-bit protection for the byte swap
:
c = bytes(3)
d = bytes(4)
if (a .lt. 0) a = a + 256
if (b .lt. 0) b = b + 256
:

bytes is declared as INTEGER*1 but should be BYTE ?

You probably also want to fix 'htons' to use BYTE variables in an equivalence instead of signed math to switch bytes.

There are existing functions for this! (somewhere)

Sorry, no Fortran/Ucx compile environment handy to try.

Be sure to search for "unsigned" in:

http://h71000.www7.hp.com/doc/82final/6443/6443pro_009.html
Mike Kier
Valued Contributor

Re: Fortran TCP/IP Programming Examples?

The proper way to move data between dissimilar types in modern Fortran (not VAX and not using /OLD_F77 on Alpha) is with the transfer intrinsic function:

dest = TRANSFER(source, mold)

so in your case it would be

a=transfer(bytes(3), a)
b=transfer(bytes(4), a)

etc.
Practice Random Acts of VMS Marketing
Darlene Riddle
Occasional Visitor

Re: Fortran TCP/IP Programming Examples?

Thanks for your answers. But that is not my problem. I am having trouble storing a large number in SIN$L_ADDR. Here is a snippet of my code:

INTEGER*8 A, B, C, D
RECORD/SOCKADDRIN/REMOTE_HOST

D = 199
C = 1
B = 1
A = 233
REMOTE_HOST.SIN$L_ADDR = (D * 256
! * 256 * 256) +
! (C * 256 * 256) +
! (B * 256) + A
Integer overflow occurs when D > 127. I had also tried declaring A-D as integer*4.
Hein van den Heuvel
Honored Contributor
Solution

Re: Fortran TCP/IP Programming Examples?

I beg to differ. It is the problem.

You are using math to move bytes.
Instead, just tell the compiler to move bytes without interpretation.

The address is declared as an integer, which in Fortran is always signed.
The address is NOT an integer, it a bunch of unsigned bytes.

The math creates a number > 2147483647
That can not be stored in 32 bit a signed integer. You could solve it by doing something hockey like doing the math into an integer*8 temp and then subtract 4*1024*1024*1024 if the value is larger than 2147483647 ( 2*1024*1024*1024-1 )

But why bother with all that if really you just want to move bytes?

fwiw,
Hein



Fekko Stubbe
Valued Contributor

Re: Fortran TCP/IP Programming Examples?

Had a problem with the web. retry
structure /address/
union
map
integer*4 l_address
end map
map
byte b_addr(4)
end map
end union
end structure
record /adress/address
c
c now fill address.b_addr(1..4)with the bytes
c and then sin$l_addr= address.l_address
Mike Kier
Valued Contributor

Re: Fortran TCP/IP Programming Examples?

Again, stay within standard Fortran. You are moving bits, so use the movbits intrinsic subroutine.

Call mvbits (a, 1, 8, REMOTE_HOST.SIN$L_ADDR, 1)
Call mvbits (b, 1, 8, REMOTE_HOST.SIN$L_ADDR, 9)
Call mvbits (c, 1, 8, REMOTE_HOST.SIN$L_ADDR, 17)
Call mvbits (d, 1, 8, REMOTE_HOST.SIN$L_ADDR, 25)
Practice Random Acts of VMS Marketing
Darlene Riddle
Occasional Visitor

Re: Fortran TCP/IP Programming Examples?

Thanks for your answers. I moved each byte into the integer value and it works now.