Ubuntu中Fortran网络编程入门
导读: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
