0

从这个rpg 套接字教程中,我们在 rpg 中创建了一个调用 java 服务器套接字的套接字客户端

问题是 connect()/send() 操作阻塞,我们有一个要求,如果连接/发送不能在一秒钟内完成,我们必须记录它并完成。

如果我将套接字设置为非阻塞模式(我认为使用 fnctl),我们并不完全了解如何进行,并且找不到任何有用的文档和示例。

我想如果我确实连接到一个非阻塞套接字,我必须执行 select(..., timeout) 这告诉我们连接是否成功和/我们是否能够发送(字节)。但是,如果我们之后 send(bytes),因为它现在是一个非阻塞套接字(在调用后将立即返回),我怎么知道 send() 在关闭之前将字节实际发送到服务器插座 ?

我可以回退到将 AS400 中的客户端套接字作为 Java 或 C 程序,但我真的只想将它保留在一个简单的 RPG 程序中。

有人能帮我理解怎么做吗?谢谢 !

4

1 回答 1

2

在我看来,你提到的那个RPG教程有一点缺陷。我认为引起您困惑的是以下部分的代码:

...
因此,我们通常像这样调用 send() API:

D miscdata        S             25A
D rc              S             10I 0

C                   eval      miscdata = 'The data to send goes here'
C                   eval      rc = send(s: %addr(miscdata): 25: 0)
c                   if        rc < 25
C*  for some reason we weren't able to send all 25 bytes!
C                   endif

...

如果您阅读文档,send()您会看到如果返回值大于 -1,则返回值并不表示错误,但在上面的代码中,似乎发生了错误。事实上,返回值的总和必须等于缓冲区的大小,假设您不断将指针移动到缓冲区中以反映已发送的内容。在Beej 的网络编程指南中查看此处。您可能还想查看 Richard Stevens 的书UNIX Network Programming, Volume 1以获得非常详细的解释。

至于确定之前的最后一次发送是否close()是实际发送的问题......上面的段落解释了如何确定数据的哪一部分被发送。但是,调用close()将尝试发送所有未发送的数据,除非SO_LINGER设置。

fnctl()用于控制阻塞,而setsockopt()用于设置SO_LINGER

正在使用的网络通信的抽象是 BSD 套接字。跨操作系统的实现有一些细微的差异,但通常是相当同质的。这意味着人们通常可以使用为其他操作系统编写的文档来进行广泛的概述。大多数时候

于 2010-08-28T22:50:33.677 回答