ubuntu

Ubuntu中Fortran网络编程入门

小樊
38
2025-12-22 07:26:24
栏目: 智能运维

Ubuntu 下 Fortran 网络编程入门

一 环境准备

二 方案一 调用 C 的 Socket API 入门

program tcp_echo_minimal
  use, intrinsic :: iso_c_binding
  implicit none
  integer(c_int), parameter :: AF_INET = 2, SOCK_STREAM = 1, IPPROTO_TCP = 6
  integer(c_int) :: server_fd, client_fd, n
  character(len=256) :: buf
  ! 声明 C 函数接口
  interface
    function socket(domain, type, protocol) bind(C, name="socket")
      import c_int; integer(c_int), value :: domain, type, protocol; integer(c_int) :: socket
    end function socket
    function bind(sockfd, addr, addrlen) bind(C, name="bind")
      import c_int, c_ptr; integer(c_int), value :: sockfd; type(c_ptr), value :: addr, addrlen; integer(c_int) :: bind
    end function bind
    function listen(sockfd, backlog) bind(C, name="listen")
      import c_int; integer(c_int), value :: sockfd, backlog; integer(c_int) :: listen
    end function listen
    function accept(sockfd, addr, addrlen) bind(C, name="accept")
      import c_int, c_ptr; integer(c_int), value :: sockfd; type(c_ptr), value :: addr, addrlen; integer(c_int) :: accept
    end function accept
    function recv(sockfd, buf, len, flags) bind(C, name="recv")
      import c_int; integer(c_int), value :: sockfd, len, flags; character(kind=c_char) :: buf(*); integer(c_int) :: recv
    end function recv
    function send(sockfd, buf, len, flags) bind(C, name="send")
      import c_int; integer(c_int), value :: sockfd, len, flags; character(kind=c_char) :: buf(*); integer(c_int) :: send
    end function send
    subroutine close(fd) bind(C, name="close")
      import c_int; integer(c_int), value :: fd
    end subroutine close
  end interface

  server_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
  if (server_fd < 0) stop 'socket failed'

  ! TODO: 使用 c_loc 与 C 的 sockaddr_in 正确设置地址与端口(含 htons/INADDR_ANY),然后 bind/listen/accept
  ! client_fd = accept(server_fd, ...)
  ! do
  !   n = recv(client_fd, buf, len(buf), 0)
  !   if (n <= 0) exit
  !   call send(client_fd, buf, n, 0)
  ! end do
  ! call close(client_fd); call close(server_fd)
end program tcp_echo_minimal

三 方案二 使用 libcurl 发起 HTTP 请求

program http_get
  use, intrinsic :: iso_c_binding
  implicit none
  interface
    function curl_easy_init() bind(C, name="curl_easy_init") result(curl)
      import c_ptr; type(c_ptr) :: curl
    end function curl_easy_init
    function curl_easy_setopt(curl, opt, param) bind(C, name="curl_easy_setopt")
      import c_ptr, c_int; type(c_ptr), value :: curl; integer(c_int), value :: opt; type(c_ptr), value :: param; integer(c_int) :: curl_easy_setopt
    end function curl_easy_setopt
    function curl_easy_perform(curl) bind(C, name="curl_easy_perform")
      import c_ptr, c_int; type(c_ptr), value :: curl; integer(c_int) :: curl_easy_perform
    end function curl_easy_perform
    subroutine curl_easy_cleanup(curl) bind(C, name="curl_easy_cleanup")
      import c_ptr; type(c_ptr), value :: curl
    end interface

  type(c_ptr) :: curl
  character(len=*), parameter :: URL = "http://example.com" // c_null_char
  integer(c_int) :: res

  curl = curl_easy_init()
  if (curl == c_null_ptr) then
    print *, "curl init failed"
    stop
  end if

  call curl_easy_setopt(curl, 10002_c_int, c_loc(URL))  ! CURLOPT_URL
  call curl_easy_setopt(curl, 52_c_int, 1_c_int)       ! CURLOPT_FOLLOWLOCATION
  res = curl_easy_perform(curl)
  if (res /= 0) then
    print *, "curl_easy_perform failed: ", res
  end if

  call curl_easy_cleanup(curl)
end program http_get

四 常见问题与排查

0
看了该问题的人还看了