- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I can't seem to find any working examples of programming with sockets in Fortran. Does anyone have
a good resource on this subject.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Programming with sockets was mentioned here by Jugoslav Dujic but link to some examples is not working now. I think resources are only in C language.
If you need only functionality of http and ftp you can try wininet extension of sockets from microsoft (I am adding small example, you should link it agains wininet.lib)[fortran]use dfwinty
integer(HANDLE) hInternet
integer(HANDLE) hFile
character*10000 buffer
integer*4 iRead
logical*4 bret
integer*4,parameter :: INTERNET_OPEN_TYPE_DIRECT =1
integer*4,parameter :: INTERNET_FLAG_NO_CACHE_WRITE =#04000000
interface
integer(handle) function InternetOpen(d0,d1,d2,d3,d4)
use dfwinty
!DEC$ ATTRIBUTES DEFAULT :: InternetOpen
!DEC$IF DEFINED(_X86_)
!DEC$ ATTRIBUTES STDCALL, ALIAS : '_InternetOpenA@20' :: InternetOpen
!DEC$ELSE
!DEC$ ATTRIBUTES STDCALL, ALIAS : 'InternetOpenA' :: InternetOpen
!DEC$ENDIF
!DEC$ ATTRIBUTES REFERENCE :: d0,d2,d3
!InternetOpenA(LPCSTR ,DWORD ,LPCSTR ,LPCSTR ,DWORD);
character*(*) d0,d2,d3
integer*4 d1,d4
end function
integer(handle) function InternetOpenUrl(d0,d1,d2,d3,d4,d5)
use dfwinty
!DEC$ ATTRIBUTES DEFAULT :: InternetOpenUrl
!DEC$IF DEFINED(_X86_)
!DEC$ ATTRIBUTES STDCALL, ALIAS : '_InternetOpenUrlA@24' :: InternetOpenUrl
!DEC$ELSE
!DEC$ ATTRIBUTES STDCALL, ALIAS : 'InternetOpenUrlA' :: InternetOpenUrl
!DEC$ENDIF
!DEC$ ATTRIBUTES REFERENCE :: d1,d2
! InternetOpenUrlA(HINTERNET ,LPCSTR ,LPCSTR ,DWORD ,DWORD ,DWORD_PTR);
character*(*) d1,d2
integer*4 d3,d4
integer(HANDLE) d0,d5
end function
logical*4 function InternetReadFile(d0,d1,d2,d3)
use dfwinty
!DEC$ ATTRIBUTES DEFAULT :: InternetReadFile
!DEC$IF DEFINED(_X86_)
!DEC$ ATTRIBUTES STDCALL, ALIAS : '_InternetReadFile@16' :: InternetReadFile
!DEC$ELSE
!DEC$ ATTRIBUTES STDCALL, ALIAS : 'InternetReadFile' :: InternetReadFile
!DEC$ENDIF
!DEC$ ATTRIBUTES REFERENCE :: d1,d3
! InternetReadFile( HINTERNET ,LPVOID ,DWORD ,LPDWORD );
character*(*) d1
integer*4 d2,d3
integer(HANDLE) d0
end function
logical*4 function InternetCloseHandle(d0)
use dfwinty
!DEC$ ATTRIBUTES DEFAULT :: InternetCloseHandle
!DEC$IF DEFINED(_X86_)
!DEC$ ATTRIBUTES STDCALL, ALIAS : '_InternetCloseHandle@4' :: InternetCloseHandle
!DEC$ELSE
!DEC$ ATTRIBUTES STDCALL, ALIAS : 'InternetCloseHandle' :: InternetCloseHandle
!DEC$ENDIF
integer(HANDLE) d0
end function
end interface
hInternet = InternetOpen("Test"C, INTERNET_OPEN_TYPE_DIRECT, NULL_CHARACTER,&
NULL_CHARACTER,&
INTERNET_FLAG_NO_CACHE_WRITE)
hFile = InternetOpenUrl( hInternet, "http://www.google.com", NULL_CHARACTER, 0, 0, 0 ) ;
ibuffer=1
do while (InternetReadFile( hFile, buffer(ibuffer:ibuffer), len(buffer)-ibuffer+1, iRead))
if ( iRead == 0) then
exit
endif
ibuffer=ibuffer+iread
enddo
bret=InternetCloseHandle(hFile)
bret=InternetCloseHandle(hInternet)
[/fortran]
Jakub
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If you email me g.bogle@auckland.ac.nz I'll send you the code I'm using.
Gib
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you for the reply. I do got this error:
error #6404: This name does not have a type, and must have an explicit type. [IBUFFER]
and wonder if inbuffer is something that I should declare or am i missing a USE module.
and since I get this error a syntax error for "logicallogical*4 bret" in this example, I
wonder if thats where I buffer should be declared. I dont think so, however since I buffer appears
to be a character array.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
ibuffer is counter variable so it is integer*4.
My example may miss some declarations, because I get it from my real code and did not tested it if it is ok. If you will have problems to make it work I can prepare working example.
I am sorry.
Jakub
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The source code is located at the following link.
https://github.com/lassytouton/LittleDemos/tree/master/Intel%20Visual%20FORTRAN%20TCP%20IP%20Sockets%20Based%20Client%20Server
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
My colleague and I decided yesterday to implement sockets based communication between processes (so you dont need to have both processes on one machine).
I will look through it.
I have an older link in my favourites list, but I dont know, if it works. Its about Winsocks...
http://prasinos.blog2.fc2.com/blog-entry-21.html
Markus
Edit: I formatted the source code of the link and I had to add line 101 to get it compiled...
[bash]module winsock_types implicit none type wsadata integer(2):: version integer(2):: highversion character(257):: szDescription character(129):: szSystemStatus integer(2):: maxSockets integer(2):: maxUdpdg integer(4):: lpVenderinfo end type type sockaddr_in sequence integer(2):: sin_family integer(2):: sin_port integer(4):: sin_addr integer(4):: sin_zero(2) end type type socket_t integer(4):: ival end type type hostent_t integer(4):: h_name integer(4):: h_aliases integer(2):: h_addrtype integer(2):: h_length integer(4):: h_addr_list end type end module module winsock use winsock_types implicit none interface integer(4) function wsastartup(reqver, wsainfo) !dec$ attributes dllimport, alias: '_WSAStartup@8' :: WSAStartup use winsock_types integer(2), intent(in):: reqver !dec$ attributes value:: reqver type(wsadata), intent(out):: wsainfo end function integer(4) function wsacleanup() !dec$ attributes stdcall, dllimport, alias: '_WSACleanup@0' :: WSACleanup end function integer(4) function wsagetlasterror() !dec$ attributes stdcall, dllimport, alias: '_WSAGetLastError@0' :: WSAGetLastError end function function socket(af, type, protocol) result(result) !dec$ attributes stdcall, dllimport, alias: '_socket@12' :: socket use winsock_types integer(4), intent(in):: af integer(4), intent(in):: type integer(4), intent(in):: protocol type(socket_t):: result end function integer(4) function closesocket(s) !dec$ attributes stdcall, dllimport, alias: '_closesocket@4' :: closesocket use winsock_types type(socket_t), intent(in):: s end function end interface integer(4), parameter:: AF_UNIX = 1 integer(4), parameter:: AF_INET = 2 integer(4), parameter:: AF_INET6 = 23 integer(4), parameter:: SOCK_STREAM = 1 integer(4), parameter:: SOCK_DGRAM = 2 type(socket_t), parameter:: INVALID_SOCKET = socket_t(not(0)) integer(4), parameter:: SOCKET_ERROR = -1 type(sockaddr_in), parameter:: SOCKADDR_IN_ANY = sockaddr_in(AF_INET, 0, & & 0, (/2 * 0/)) interface operator(==) module procedure socket_eq end interface interface integer(4) function bind(s, name, namelen) !dec$ attributes stdcall, dllimport, alias: '_bind@12' :: bind use winsock_types type(socket_t), intent(in):: s type(sockaddr_in), intent(in):: name !dec$ attributes reference:: name integer(4), intent(in):: namelen end function function accept(s, addr, addrlen) result(result) !dec$ attributes stdcall, dllimport, alias: '_accept@12' :: accept !DEC$ ATTRIBUTES REFERENCE :: addrlen use winsock_types type(socket_t), intent(in):: s type(sockaddr_in), intent(out):: addr !dec$ attributes reference:: addr integer(4), intent(out):: addrlen type(socket_t):: result end function ! GUISE: return value is pointer to HOSTENT structure integer(4) function gethostbyname(szname) !dec$ attributes stdcall, dllimport, alias: '_gethostbyname@4' :: gethostbyname character(*), intent(in):: szname !dec$ attributes reference:: szname end function integer(4) function inet_addr(szname) !dec$ attributes stdcall, dllimport, alias: '_inet_addr@4' :: inet_addr character(*), intent(in):: szname !dec$ attributes reference:: szname end function integer(4) function connect(s, name, namelen) !dec$ attributes stdcall, dllimport, alias: '_connect@12' :: connect use winsock_types type(socket_t), intent(in):: s type(sockaddr_in), intent(in):: name !dec$ attributes reference:: name integer(4), intent(in):: namelen end function end interface interface send integer(4) function sendc(s, buf, len, flags) !dec$ attributes stdcall, dllimport, alias: '_send@16' :: sendc use winsock_types type(socket_t), intent(in):: s character(*), intent(in):: buf !dec$ attributes reference:: buf integer(4), intent(in):: len, flags end function integer(4) function send4(s, buf, len, flags) !dec$ attributes stdcall, dllimport, alias: '_send@16' :: send4 use winsock_types type(socket_t), intent(in):: s integer, intent(in):: buf(*) !dec$ attributes reference:: buf integer(4), intent(in):: len, flags end function end interface interface recv integer(4) function recvc(s, buf, len, flags) !dec$ attributes stdcall, dllimport, alias: '_recv@16' :: recvc use winsock_types type(socket_t), intent(in):: s character(*), intent(out):: buf !dec$ attributes reference:: buf integer(4), intent(in):: len, flags end function integer(4) function recv4(s, buf, len, flags) !dec$ attributes stdcall, dllimport, alias: '_recv@16' :: recv4 use winsock_types type(socket_t), intent(in):: s integer, intent(out):: buf(*) !dec$ attributes reference:: buf integer(4), intent(in):: len, flags end function end interface contains logical function socket_eq(s1, s2) result(result) type(socket_t), intent(in):: s1, s2 result = s1%ival == s2%ival end function type(sockaddr_in) function make_sockaddr_in(name, port) result(result) character(*), intent(in):: name integer, intent(in):: port character(2048):: namebuf integer:: namelen integer(4):: addr, ival type(HOSTENT_T):: hostent integer(1):: bval(4) integer:: i pointer(addr, hostent) pointer(addr, ival) pointer(addr, bval) namebuf = name namelen = min(len(namebuf), len_trim(namebuf) + 1) namebuf(namelen:namelen) = char(0) addr = inet_addr(namebuf) if (addr /= not(0_4)) then result%sin_addr = addr else addr = gethostbyname(namebuf) if (addr == 0) then result%sin_addr = 255 result%sin_port = 0 return endif addr = hostent%h_addr_list addr = ival result%sin_addr = ival endif result%sin_family = AF_INET ! result%sin_port = port result%sin_port = ior(ishft(iand(255, port), 8), iand(ishft(port, -8), 255)) result%sin_zero(:) = 0 end function character(60) function wsastrerror(errno) result(result) integer, intent(in), optional:: errno integer:: error_code if (present(errno)) then error_code = errno else error_code = wsagetlasterror() endif select case(error_code) case(10004); result = "interrupted function call" case(10009); result = "EBADF" case(10013); result = "permission denied" case(10014); result = "bad address" case(10022); result = "invalid function argument" case(10024); result = "too many open files" case(10035); result = "resource temporarily unavailable" case(10036); result = "operation now in progress" case(10037); result = "operation already in progress" case(10038); result = "socket operation on non-socket" case(10039); result = "destination address required" case(10040); result = "message too long" case(10041); result = "protocl wrong type for socket" case(10042); result = "bad protocol option" case(10043); result = "protocol not supported" case(10044); result = "socket type not supported" case(10045); result = "operation not supported" case(10046); result = "protocol family not supported" case(10047); result = "address family not supported by protocol family" case(10048); result = "address already in use" case(10049); result = "cannot assign requested address" case(10050); result = "network is down" case(10051); result = "network is unreachable" case(10052); result = "network dropped connection on reset" case(10053); result = "software caused connection abort" case(10054); result = "connection reset by peer" case(10055); result = "no buffer space is available" case(10056); result = "socket is already connected" case(10057); result = "socket is not connected" case(10058); result = "cannot send after socket shutdown" case(10059); result = "ETOOMANYREFS" case(10060); result = "connection timed out" case(10061); result = "connection refused" case(10062); result = "ELOOP" case(10063); result = "ENAMETOOLONG" case(10064); result = "host is down" case(10065); result = "no route to host" case(10066); result = "ENOTEMPTY" case(10067); result = "too many processes" case(10068); result = "EUSERS" case(10069); result = "EDQUOT" case(10070); result = "ESTALE" case(10071); result = "EREMOTE" case(10091); result = "network subsystem is unavailable" case(10092); result = "WINSOCK.DLL version out of range" case(10093); result = "successful WSAStartup not yet performed" case(10094); result = "graceful shutdown in progress" case(10101); result = "DISCON" case(10102); result = "NOMORE" case(10103); result = "CANCELLED" case(10104); result = "invalid procedure table from service provider" case(10105); result = "invalid service provider version number" case(10106); result = "unable to initialize a service provider" case(10107); result = "system call failure" case(10108); result = "SERVICE_NOT_FOUND" case(10109); result = "class type not found" case(10110); result = "NO_MORE" case(10111); result = "CANCELLED" case(10112); result = "REFUSED" case(11001); result = "authoritative DNS answer: host not found" case(11002); result = "non-authoritative: host not found; or server fail" case(11003); result = "non-recoverable DNS error FORMERR, REFUSED, or NOTIMP" case(11004); result = "no DNS data record of requested type" case default result = "" write(unit=result, fmt="('unknown Winsock error ',i12.1)") error_code end select end function character(1024) function sz2char(sz) result(result) character(*), intent(in):: sz character:: c integer:: i, j j = 1 do, i = 1, len(sz) if ((j + 4) > len(result)) exit c = sz(i:i) select case(ichar(c)) case(0) exit case(92) result(j:j+1) = c // c j = j + 2 case(10) result(j:j+1) = char(92) // 'n' j = j + 2 case(13) result(j:j+1) = char(92) // 'r' j = j + 2 case(1:9, 11, 12, 14:31, 127:255) write(result(j:j+3), "(A2, Z2.2)") char(92) // 'x', ichar(c) j = j + 4 case default result(j:j) = c j = j + 1 end select enddo if (j < len(result)) then result(j: ) = '' endif end function end module subroutine main use winsock implicit none type(wsadata):: wsainfo integer(2):: reqver integer(4):: i type(socket_t):: s type(sockaddr_in):: sa character(1024):: buf reqver = 514 i = wsastartup(reqver, wsainfo) print *, "WSAStartup =", i, wsainfo%version, wsainfo%highversion, & & "'"//trim(sz2char(wsainfo%szDescription))//"'("//trim(sz2char(wsainfo%szSystemStatus))//")" if (i /= 0) then stop 16 endif s = socket(AF_INET, SOCK_STREAM, 0) print *, 'socket', s if (s == INVALID_SOCKET) then print *, 'socket:', wsastrerror() goto 900 endif sa = make_sockaddr_in("www.asahi.com", 80) print *, ibits(sa%sin_addr, 0, 8), ibits(sa%sin_addr, 8, 8), & & ibits(sa%sin_addr, 16, 8), ibits(sa%sin_addr, 24, 8), & & ibits(sa%sin_port, 0, 8), ibits(sa%sin_port, 8, 8) if (sa%sin_port == 0) goto 900 i = connect(s, sa, 16) print *, 'connect', i if (i == SOCKET_ERROR) then print *, 'connect:', wsastrerror() goto 910 endif i = send(s, "GET /" // char(13) // char(10), 7, 0) if (i == SOCKET_ERROR) then print *, 'send:', wsastrerror() goto 910 endif do i = recv(s, buf, len(buf), 0) if (i == SOCKET_ERROR) then print *, 'recv:', wsastrerror() goto 910 endif if (i == 0) exit print *, buf(1:i) enddo 910 continue print *, 'closesocket', closesocket(s) print *, "WSACleanup =", wsacleanup() print *, "OK" return 900 continue print *, "WSACleanup =", wsacleanup() print *, "OK" end subroutine call main end[/bash]
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Best regards,
Sergey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I've updated my GitHub project demonstrating how to implement a TCP/IP sockets based client and server using Intel Visual FORTRAN... there was a bug in the original SendMsg routine implementation. This has now been fixed. The source code is located at the following link. https://github.com/lassytouton/LittleDemos/tree/master/Intel%20Visual%20FORTRAN%20TCP%20IP%20Sockets%20Based%20Client%20Server
![](/skins/images/8B6E2C8F64F54CBD7F7262AA46F575DA/responsive_peak/images/icon_anonymous_message.png)
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page