首页主机资讯Ubuntu中Fortran网络编程入门

Ubuntu中Fortran网络编程入门

时间2025-12-22 09:21:04发布访客分类主机资讯浏览297
导读:Ubuntu 下 Fortran 网络编程入门 一 环境准备 安装编译器:在终端执行 sudo apt update && sudo apt install gfortran,完成后用 gfortran --version...

Ubuntu 下 Fortran 网络编程入门

一 环境准备

  • 安装编译器:在终端执行 sudo apt update & & sudo apt install gfortran,完成后用 gfortran --version 验证。
  • 选择技术路线:
    • 直接调用系统 Socket API(通过 ISO_C_BINDING 与 C 的 socket 函数对接)。
    • 使用现成的高层库(如 libcurl 做 HTTP/HTTPS/FTP)。
  • 安装常用库:做 HTTP 示例时执行 sudo apt install libcurl4-openssl-dev。
  • 防火墙与端口:若测试远程访问,放行对应端口(如 12345),例如 sudo ufw allow 12345/tcp。
  • 说明:Fortran 标准库不直接提供网络功能,工程上常用“C 接口”或“高层网络库”两种方式实现。

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

  • 思路要点:用 ISO_C_BINDING 声明并调用 C 的 socket/bind/listen/accept/recv/send/close 等函数;按 C 的语义准备地址结构(如 struct sockaddr_in)、字节序(htons)与缓冲区;注意错误处理与资源释放。
  • 最小可运行骨架(示意,需补充错误处理与地址设置):
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
  • 编译与运行:gfortran -o server server.f90;./server。提示:Linux 上通常无需额外链接“socket 库”,直接 gfortran 即可;若报错再按需添加系统库。
  • 实践建议:先完成“回显服务器”(接收后原样发回),再补充地址重用(SO_REUSEADDR)、超时、信号与并发等。

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

  • 适用场景:需要 HTTP/HTTPS 等高层协议时,直接调用 libcurl 更省事。
  • 安装库:sudo apt install libcurl4-openssl-dev。
  • 最小示例(HTTP GET,需启用 C 互操作与错误检查):
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
  • 编译与运行:gfortran -o http_get http_get.f90 -lcurl;./http_get。
  • 提示:libcurl 提供丰富的选项(Header、POST、超时、证书校验等),可按需扩展。

四 常见问题与排查

  • 编译链接问题:
    • 纯 socket 示例一般无需额外库,直接 gfortran 即可;若提示未定义引用,再考虑系统库。
    • 使用 libcurl 必须加 -lcurl。
  • 端口与防火墙:确认程序监听的端口(如 12345)已在防火墙放行,且未被占用(ss -ltnp | grep 12345)。
  • 地址与字节序:服务器地址应使用 INADDR_ANY 以监听所有接口;端口用 htons 转为网络字节序。
  • 错误处理:检查 socket/bind/listen/accept/recv/send/close 的返回值;对关键调用加入条件分支与日志输出。
  • 资源释放:确保 accept 成功后对 client_fd 执行 close,程序退出前关闭 server_fd,避免文件描述符泄漏。

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!


若转载请注明出处: Ubuntu中Fortran网络编程入门
本文地址: https://pptw.com/jishu/777068.html
Ubuntu上Fortran图形界面开发技巧 Ubuntu下Fortran多线程编程指南

游客 回复需填写必要信息