一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

Ubuntu中Fortran网络编程入门

时间:2026-08-03 12:16:50 编辑:袖梨 来源:一聚教程网

Ubuntu 下 Fortran 网络编程入门

Ubuntu中Fortran网络编程入门

一 环境准备

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

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

  1. 思路要点:用 ISO_C_BINDING 声明并调用 C 的 socket/bind/listen/accept/recv/send/close 等函数;按 C 的语义准备地址结构(如 struct sockaddr_in)、字节序(htons)与缓冲区;注意错误处理与资源释放。
  2. 最小可运行骨架(示意,需补充错误处理与地址设置):
program tcp_echo_minimaluse, intrinsic :: iso_c_bindingimplicit noneinteger(c_int), parameter :: AF_INET = 2, SOCK_STREAM = 1, IPPROTO_TCP = 6integer(c_int) :: server_fd, client_fd, ncharacter(len=256) :: buf! 声明 C 函数接口interfacefunction socket(domain, type, protocol) bind(C, name="socket")import c_int; integer(c_int), value :: domain, type, protocol; integer(c_int) :: socketend function socketfunction 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) :: bindend function bindfunction listen(sockfd, backlog) bind(C, name="listen")import c_int; integer(c_int), value :: sockfd, backlog; integer(c_int) :: listenend function listenfunction 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) :: acceptend function acceptfunction 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) :: recvend function recvfunction 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) :: sendend function sendsubroutine close(fd) bind(C, name="close")import c_int; integer(c_int), value :: fdend subroutine closeend interfaceserver_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
  1. 编译与运行:gfortran -o server server.f90;./server。提示:Linux 上通常无需额外链接“socket 库”,直接 gfortran 即可;若报错再按需添加系统库。
  2. 实践建议:先完成“回显服务器”(接收后原样发回),再补充地址重用(SO_REUSEADDR)、超时、信号与并发等。

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

  1. 适用场景:需要 HTTP/HTTPS 等高层协议时,直接调用 libcurl 更省事。
  2. 安装库:sudo apt install libcurl4-openssl-dev。
  3. 最小示例(HTTP GET,需启用 C 互操作与错误检查):
program http_getuse, intrinsic :: iso_c_bindingimplicit noneinterfacefunction curl_easy_init() bind(C, name="curl_easy_init") result(curl)import c_ptr; type(c_ptr) :: curlend function curl_easy_initfunction 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_setoptend function curl_easy_setoptfunction 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_performend function curl_easy_performsubroutine curl_easy_cleanup(curl) bind(C, name="curl_easy_cleanup")import c_ptr; type(c_ptr), value :: curlend interfacetype(c_ptr) :: curlcharacter(len=*), parameter :: URL = "http://example.com" // c_null_charinteger(c_int) :: rescurl = curl_easy_init()if (curl == c_null_ptr) thenprint *, "curl init failed"stopend ifcall curl_easy_setopt(curl, 10002_c_int, c_loc(URL))! CURLOPT_URLcall curl_easy_setopt(curl, 52_c_int, 1_c_int) ! CURLOPT_FOLLOWLOCATIONres = curl_easy_perform(curl)if (res /= 0) thenprint *, "curl_easy_perform failed: ", resend ifcall curl_easy_cleanup(curl)end program http_get
  1. 编译与运行:gfortran -o http_get http_get.f90 -lcurl;./http_get。
  2. 提示:libcurl 提供丰富的选项(Header、POST、超时、证书校验等),可按需扩展。

四 常见问题与排查

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

热门栏目