Ubuntu 下 Fortran 网络编程入门

一 环境准备
二 方案一 调用 C 的 Socket API 入门
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三 方案二 使用 libcurl 发起 HTTP 请求
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四 常见问题与排查