Fortran Coder

查看: 14290|回复: 14
打印 上一主题 下一主题

[绘图界面库] fortran语言实现socket通信/winsock

[复制链接]

954

帖子

0

主题

0

精华

大师

F 币
184 元
贡献
75 点

规矩勋章元老勋章新人勋章水王勋章热心勋章

QQ
楼主
发表于 2015-7-27 22:02:34 | 显示全部楼层
首先你要知道,语言本身并没有,也不会有socket通讯功能。
其实C语言本身也不规定如何使用 socket,它只规定逻辑关系和数学计算的写法。
具体到各平台下的实现,是编译器和第三方库的事情。
换过来说,socket 是一个网络通讯规范,本身也不规定如何使用。像 winsock 一类的库才是它的实现,类似的还有 Java 的 Jsocket 接口等等。注意 winsock 不等于 socket。
理解了这两个问题,才能回到你的问题上。如果你是在 windows 上 intel fortran 通过 winsock 来实现的话,那么可以 Use ws2_32 来使用 windows 标准的 ws2_32 的 API 库实现。
如果你是在其他平台(Linux),使用其他编译器,通过其他 socket 的接口(如LSocket,ServerSocket等)实现,那么用法会不一样。这一点请你深刻理解!

以下是我曾经写过的一个 UDP 协议的封装。仅供参考,具体细节请翻阅 winsock 文档!

注意它有使用局限性:
1.仅限windows,使用 winsocket接口
2.仅限Intel fortran
3.仅限 UDP 协议,TCP/IP协议请照猫画虎。

[Fortran] 纯文本查看 复制代码
Module SocketMod
  Use ws2_32 , ID_Cancel => IDCancel
  Use kernel32 , only : sleep
  Implicit None  
  Type t_sockaddr_union
    Sequence
    union
      map
        Type (t_sockaddr_in) sockaddrin
      end map
      map
        Type (t_sockaddr) sockaddr
      end map
    end union
  End Type t_sockaddr_union
  Integer , parameter , private :: winsock_v2_2 = x'202' , success = 0 !版本
contains

  Integer Function Socket_UDP_Conn( host , port )
    Character(len=15) host
    Integer(kind=2) port
    type (t_wsadata) WSAInfo !版本信息结构
    !integer receivelen , iSendLen     , ic
    type (t_sockaddr_union) ConnectionInfo !Client_add
    Integer hSocket , status , i
    Socket_UDP_Conn = 0
    status = WSAStartup(winsock_v2_2, WSAInfo)
    If (status/=success) return
! 创建套接字
    hSocket = Socket( af_inet , SOCK_DGRAM , ipproto_udp )
    If (hSocket==invalid_socket) goto 999
    ConnectionInfo.sockaddrin.sin_family = af_inet
    ConnectionInfo.sockaddrin.sin_port = htons( port )
    ConnectionInfo.sockaddrin.sin_addr%s_addr = inet_addr( host( 1 : len_trim(host) ) )
    status = Connect(hSocket, %ref(ConnectionInfo%sockaddr), sizeof(ConnectionInfo%sockaddr))
    If (status==socket_error) return        
    i = 1
    status = ioctlsocket( hSocket , FIONBIO , loc(1) )
    Socket_UDP_Conn = hSocket
    return
999 status = WSACleanup()
  End Function Socket_UDP_Conn
  
  Integer Function Socket_UDP_Disconn( hSocket )
    integer :: hSocket
    Socket_UDP_Disconn = CloseSocket( hSocket )
    Socket_UDP_Disconn = WSACleanup()
  End Function Socket_UDP_Disconn
  
  Integer Function Socket_UDP_Send( hSocket , c , len_c )
    Character(len=*) :: c
    Integer :: len_c    
    Integer hSocket , iSendLen
    Socket_UDP_Send = 0
    iSendLen = Send( hSocket , c , len_c , 0 )
    If ( iSendLen < 0 ) return
    Socket_UDP_Send = 1
  End Function Socket_UDP_Send
  
  Integer Function Socket_UDP_Recv( hSocket , c , len_c , timeout )
    Character(len=*) :: c
    Integer :: len_c , timeout   
    Integer :: hSocket , receivelen , i
    Socket_UDP_Recv = 0
    c = char(0)
    do i = 1 , timeout
      receivelen = Recv( hSocket , c , len_c , 0 )
      If ( receivelen == len_c ) goto 999
      call sleep(10)
    end do
    return
999 Socket_UDP_Recv = 1
  End Function Socket_UDP_Recv
  
End Module SocketMod


954

帖子

0

主题

0

精华

大师

F 币
184 元
贡献
75 点

规矩勋章元老勋章新人勋章水王勋章热心勋章

QQ
沙发
发表于 2015-7-28 08:19:01 | 显示全部楼层
C++的书讲到 socket 也是正常的,但应该会告诉你,这是具体实现,而非 C++ 的语法。
我不清楚你看到的部分,是否是通过 winsock 接口的
正如我前面所说,winsock不等于socket,前者是后者的一个实现方式,而后者是一种通讯规范。
就好像 USB 是通讯规范,而 U 盘是具体的实现。实际上,一些鼠标,风扇,充电器也使用 USB接口


你可以学习底层的 socket 通讯协议,但是这似乎没什么卵用。因为你很难在底层上实现 socket。
大多数应用程序的程序员,都是使用 winsock 或 Jsocket 或其他实现来搞。

例如 winsock,是windows封装的socket协议接口,注意是接口。
那么,如果你打算用 winsock,你可以查看winsock相关的资料,例如 MSDN library,找 winsock 的资料时,请忘记 Fortran
等学会 winsock 以后,再来学习如何用 Fortran 来调用它。

其实 winsock 一共只有20多个函数,常用的只有七八个,如我的代码里提到的
WSAStartup
Socket
Connect
ioctlsocket
WSACleanup
Send
Recv

,还是比较简单的。(任何语言通过 winsock 接口操作,使用到的函数都是相同的,只是写法会有差异)

954

帖子

0

主题

0

精华

大师

F 币
184 元
贡献
75 点

规矩勋章元老勋章新人勋章水王勋章热心勋章

QQ
板凳
发表于 2015-8-11 08:24:59 | 显示全部楼层
我不知道你的发送方是什么,代码是怎么样的。
从表现来看,后面的不是文本内容,是二进制内容。
您需要登录后才可以回帖 登录 | 极速注册

本版积分规则

捐赠本站|Archiver|关于我们 About Us|小黑屋|Fcode ( 京ICP备18005632-2号 )

GMT+8, 2024-5-8 07:44

Powered by Tencent X3.4

© 2013-2024 Tencent

快速回复 返回顶部 返回列表