从这个rpg socket tutorial我们在rpg中创建了一个调用java服务器套接字的套接字客户端
问题是connect()/ send()操作阻塞,我们要求如果连接/发送无法在每秒钟内完成,我们必须记录并完成。
如果我将套接字设置为非阻塞模式(我认为使用fnctl),我们并不完全了解如何继续,并且找不到任何有用的文档及其示例。
我认为如果我连接到非阻塞套接字,我必须选择(...,timeout)告诉我们连接是否成功和/我们是否能够发送(字节)。但是,如果我们之后发送(字节),因为它现在是一个非阻塞套接字(它会在调用后立即返回),我怎么知道send()在关闭之前实际将字节发送到服务器socket?
我可以退回到AS400中的客户端套接字作为Java或C程序,但我真的想把它保存在一个简单的RPG程序中。
有人会帮我理解怎么做吗? 谢谢!
答案 0 :(得分:2)
在我看来,你提到的RPG教程有一点点缺陷。我认为导致您混淆的是以下section's代码:
...
因此,我们通常称之为 像这样发送()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,则在上面的代码中它似乎没有出现错误。实际上,返回值的总和必须等于缓冲区的大小,假设您继续将指针移动到缓冲区以反映已发送的内容。在here中查看Beej's Guide to Network Programming。您可能还想查看Richard Stevens的书UNIX Network Programming, Volume 1以获得非常详细的解释。
关于确定close()
之前的最后一次发送是否执行实际发送的问题......以上段落解释了如何确定发送了哪些数据部分。但是,除非设置close()
,否则调用SO_LINGER
将尝试发送所有未发送的数据。
fnctl()
用于控制阻止,而setsockopt()
用于设置SO_LINGER
。
正在使用的网络通信的抽象是BSD套接字。在OS的实现中存在一些细微的差别,但它通常是非常同质的。这意味着人们通常可以使用为其他操作系统编写的文档来进行广泛的概述。 大部分时间。