之前使用的tcp相关库都对超时作了很完善的封装…换成posix之后突然不知道超时该如何设置了…
对于tcp/ip来讲,建立连接传输数据的大致过程如下:(以下代码没有释放socket,真正实用时一定要记的在适合的地方释放掉socket)
// client
1.创建一个socket(此时仅仅指定了socket的协议类型,还没有进行进行绑定,
换言之此时socket还不知道自己要和谁进行通信)
2.指明ip和port,建立连接(经过这一步,socket就知道自己需要和谁进行通信了)
3.发送数据
//server
1.创建socketA(同样的,此时server的socket也不知道自己将和谁进行通信)
2.bind(这一步指明了ip和port)
3.listen
4.accept(和client不同,server的第一步创建出来的socketA并不是真正负责通信的那个,
socketA只负责监听,对应client的connect方法,client的connect将会作用于server,
如果accept成功的话将会创建一个socketB,socketB才是真正负责通信的)
4.recv
tcp的超时
用事实来说话….首先不设置任何超时状态,按照原始tcp调用方式,使用strace查看系统调用:(长代码警告)
xxxxxxxxxxxxx:~# strace lua testTCPClient.lua
execve("/usr/bin/lua", ["lua", "testTCPClient.lua"], [/* 13 vars */]) = 0
set_thread_area(0x77eced48) = 0
set_tid_address(0x77ec7cac) = 4392
open("/etc/ld-musl-mipsel-sf.path", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/lib/liblua.so.5.1.5", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/usr/local/lib/liblua.so.5.1.5", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/usr/lib/liblua.so.5.1.5", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 3
fcntl64(3, F_SETFD, FD_CLOEXEC) = 0
fstat64(3, {st_mode=S_IFREG|0644, st_size=148372, ...}) = 0
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\10\0\1\0\0\0p8\0\0004\0\0\0"..., 936) = 936
mmap2(NULL, 196608, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0x77df4000
mmap2(0x77e22000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x1e000) = 0x77e22000
close(3) = 0
open("/lib/libgcc_s.so.1", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 3
fcntl64(3, F_SETFD, FD_CLOEXEC) = 0
fstat64(3, {st_mode=S_IFREG|0644, st_size=84152, ...}) = 0
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\10\0\1\0\0\0\0(\0\0004\0\0\0"..., 936) = 936
mmap2(NULL, 143360, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0x77dd0000
mmap2(0x77df2000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x12000) = 0x77df2000
close(3) = 0
mprotect(0x77e22000, 4096, PROT_READ) = 0
mprotect(0x412000, 4096, PROT_READ) = 0
brk(NULL) = 0x9a2000
brk(0x9a3000) = 0x9a3000
brk(0x9a4000) = 0x9a4000
brk(0x9a5000) = 0x9a5000
open("testTCPClient.lua", O_RDONLY|O_LARGEFILE) = 3
brk(0x9a6000) = 0x9a6000
readv(3, [{iov_base="", iov_len=0}, {iov_base="local socket = require(\"posix.sy"..., iov_len=1024}], 2) = 272
readv(3, [{iov_base="", iov_len=751}, {iov_base="", iov_len=1024}], 2) = 0
close(3) = 0
rt_sigprocmask(SIG_UNBLOCK, [RT_1 RT_2], NULL, 16) = 0
rt_sigaction(SIGINT, {sa_handler=0x400ea1, sa_mask=[RT_68 RT_69 RT_73 RT_74 RT_75 RT_76 RT_78 RT_81 RT_82 RT_86 RT_87 RT_88 RT_89 RT_90 RT_91 RT_93 RT_94 RT_95], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0}, {sa_handler=SIG_DFL, sa_mask=[RT_79 RT_83 RT_84 RT_86 RT_87 RT_88 RT_89 RT_90 RT_91 RT_93 RT_94 RT_95], sa_flags=0}, 16) = 0
open("./posix/sys/socket.lua", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/share/lua/posix/sys/socket.lua", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/share/lua/posix/sys/socket/init.lua", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/lua/posix/sys/socket.lua", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/lua/posix/sys/socket/init.lua", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
brk(0x9a7000) = 0x9a7000
open("./posix/sys/socket.so", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/lua/posix/sys/socket.so", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/lua/loadall.so", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("./posix.so", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/lua/posix.so", O_RDONLY|O_LARGEFILE) = 3
brk(0x9a8000) = 0x9a8000
close(3) = 0
open("/usr/lib/lua/posix.so", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 3
fcntl64(3, F_SETFD, FD_CLOEXEC) = 0
fstat64(3, {st_mode=S_IFREG|0755, st_size=90860, ...}) = 0
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\10\0\1\0\0\0\3600\0\0004\0\0\0"..., 936) = 936
mmap2(NULL, 151552, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0x77daa000
mmap2(0x77dcd000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x13000) = 0x77dcd000
close(3) = 0
mprotect(0x77dcd000, 4096, PROT_READ) = 0
brk(0x9aa000) = 0x9aa000
socket(AF_INET, SOCK_STREAM, IPPROTO_IP) = 3
connect(3, {sa_family=AF_INET, sin_port=htons(8383), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
sendto(3, "Testipv4", 8, 0, NULL, 0) = 8
recvfrom(3, "Test", 4, 0, NULL, NULL) = 4
ioctl(1, TIOCGWINSZ, 0x7f9c8078) = 0
writev(1, [{iov_base="Test", iov_len=4}, {iov_base="\n", iov_len=1}], 2Test
) = 5
open("./posix/unistd.lua", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/share/lua/posix/unistd.lua", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/share/lua/posix/unistd/init.lua", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/lua/posix/unistd.lua", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/lua/posix/unistd/init.lua", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("./posix/unistd.so", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/lua/posix/unistd.so", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/lua/loadall.so", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("./posix.so", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/lua/posix.so", O_RDONLY|O_LARGEFILE) = 4
close(4) = 0
brk(0x9ab000) = 0x9ab000
brk(0x9ad000) = 0x9ad000
close(3) = 0
rt_sigaction(SIGINT, {sa_handler=SIG_DFL, sa_mask=[RT_68 RT_69 RT_73 RT_74 RT_75 RT_76 RT_78 RT_81 RT_82 RT_86 RT_87 RT_88 RT_89 RT_90 RT_91 RT_93 RT_94 RT_95], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0}, {sa_handler=0x400ea1, sa_mask=[RT_67 RT_68 RT_72 RT_73 RT_75 RT_76 RT_77 RT_78 RT_79 RT_83 RT_84 RT_86 RT_87 RT_88 RT_89 RT_90 RT_91 RT_93 RT_94 RT_95], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0}, 16) = 0
exit_group(0) = ?
抛开加载各种库,真正用于发送的代码从57行开始,真正的发送位于59行,系统调用sendto;sendto参数如下
ssize_t sendto(int sockfd, const void buf, size_t len, int flags,const struct sockaddr dest_addr, socklen_t addrlen);
这样并看不出什么东西…所以现在让我来给client添加一个send超时(10s),再来抓一下系统调用
系统调用中多了一行
setsockopt(3, SOL_SOCKET, SO_SNDTIMEO, "\5\0\0\0\0\0\0\0", 8) = 0
int getsockopt(int sockfd, int level, int optname,void optval, socklen_t optlen);
测试
给server的recv之前添加一个大于10s的延迟,这样server不会在client发送后的5s内执行接收
local socket = require("posix.sys.socket")
local sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM,0)
socket.connect(sock,{family=socket.AF_INET,addr="127.0.0.1",port=8383})
--send out of time
socket.setsockopt(sock,socket.SOL_SOCKET,socket.SO_SNDTIMEO,5,0)
socket.setsockopt(sock,socket.SOL_SOCKET,socket.SO_RCVTIMEO,5,0)
local ok,err = socket.send(sock, 'Testipv4')
assert(ok ~= nil , err)
print(socket.recv(sock,4))
require'posix.unistd'.close(sock)
令我意外的是…发送超时并没有生效,反而是接收超时生效了….这个问题目前已经超出了我的知识范围,不过这篇文章的目的已经达到了,send超时为何没有生效的问题以后在探究…以下为本次执行的系统调用
execve("/usr/bin/lua", ["lua", "testTCPClient.lua"], [/* 13 vars */]) = 0
set_thread_area(0x779c8d48) = 0
set_tid_address(0x779c1cac) = 18836
open("/etc/ld-musl-mipsel-sf.path", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/lib/liblua.so.5.1.5", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/usr/local/lib/liblua.so.5.1.5", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/usr/lib/liblua.so.5.1.5", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 3
fcntl64(3, F_SETFD, FD_CLOEXEC) = 0
fstat64(3, {st_mode=S_IFREG|0644, st_size=148372, ...}) = 0
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\10\0\1\0\0\0p8\0\0004\0\0\0"..., 936) = 936
mmap2(NULL, 196608, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0x778ee000
mmap2(0x7791c000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x1e000) = 0x7791c000
close(3) = 0
open("/lib/libgcc_s.so.1", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 3
fcntl64(3, F_SETFD, FD_CLOEXEC) = 0
fstat64(3, {st_mode=S_IFREG|0644, st_size=84152, ...}) = 0
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\10\0\1\0\0\0\0(\0\0004\0\0\0"..., 936) = 936
mmap2(NULL, 143360, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0x778ca000
mmap2(0x778ec000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x12000) = 0x778ec000
close(3) = 0
mprotect(0x7791c000, 4096, PROT_READ) = 0
mprotect(0x412000, 4096, PROT_READ) = 0
brk(NULL) = 0x675000
brk(0x676000) = 0x676000
brk(0x677000) = 0x677000
brk(0x678000) = 0x678000
open("testTCPClient.lua", O_RDONLY|O_LARGEFILE) = 3
brk(0x679000) = 0x679000
readv(3, [{iov_base="", iov_len=0}, {iov_base="local socket = require(\"posix.sy"..., iov_len=1024}], 2) = 462
readv(3, [{iov_base="", iov_len=561}, {iov_base="", iov_len=1024}], 2) = 0
close(3) = 0
rt_sigprocmask(SIG_UNBLOCK, [RT_1 RT_2], NULL, 16) = 0
rt_sigaction(SIGINT, {sa_handler=0x400ea1, sa_mask=[RT_68 RT_69 RT_73 RT_74 RT_75 RT_76 RT_79 RT_80 RT_82 RT_85 RT_88 RT_89 RT_90 RT_91 RT_93 RT_94 RT_95], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0}, {sa_handler=SIG_DFL, sa_mask=[RT_78 RT_79 RT_80 RT_81 RT_82 RT_84 RT_85 RT_88 RT_89 RT_90 RT_91 RT_93 RT_94 RT_95], sa_flags=0}, 16) = 0
open("./posix/sys/socket.lua", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/share/lua/posix/sys/socket.lua", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/share/lua/posix/sys/socket/init.lua", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/lua/posix/sys/socket.lua", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
brk(0x67a000) = 0x67a000
open("/usr/lib/lua/posix/sys/socket/init.lua", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("./posix/sys/socket.so", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/lua/posix/sys/socket.so", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/lua/loadall.so", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("./posix.so", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/lua/posix.so", O_RDONLY|O_LARGEFILE) = 3
brk(0x67b000) = 0x67b000
close(3) = 0
open("/usr/lib/lua/posix.so", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 3
fcntl64(3, F_SETFD, FD_CLOEXEC) = 0
fstat64(3, {st_mode=S_IFREG|0755, st_size=90860, ...}) = 0
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\10\0\1\0\0\0\3600\0\0004\0\0\0"..., 936) = 936
mmap2(NULL, 151552, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0x778a4000
mmap2(0x778c7000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x13000) = 0x778c7000
close(3) = 0
mprotect(0x778c7000, 4096, PROT_READ) = 0
brk(0x67d000) = 0x67d000
socket(AF_INET, SOCK_STREAM, IPPROTO_IP) = 3
connect(3, {sa_family=AF_INET, sin_port=htons(8383), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
setsockopt(3, SOL_SOCKET, SO_SNDTIMEO, "\5\0\0\0\0\0\0\0", 8) = 0
setsockopt(3, SOL_SOCKET, SO_RCVTIMEO, "\5\0\0\0\0\0\0\0", 8) = 0
sendto(3, "Testipv4", 8, 0, NULL, 0) = 8
recvfrom(3, 0x4138b0, 4, 0, NULL, NULL) = -1 EAGAIN (Resource temporarily unavailable)
ioctl(1, TIOCGWINSZ, 0x7fe14d28) = 0
writev(1, [{iov_base="nil\tResource temporarily unavail"..., iov_len=39}, {iov_base="\n", iov_len=1}], 2nil Resource temporarily unavailable 11
) = 40
open("./posix/unistd.lua", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/share/lua/posix/unistd.lua", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/share/lua/posix/unistd/init.lua", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/lua/posix/unistd.lua", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/lua/posix/unistd/init.lua", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("./posix/unistd.so", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/lua/posix/unistd.so", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/lua/loadall.so", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("./posix.so", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/lua/posix.so", O_RDONLY|O_LARGEFILE) = 4
close(4) = 0
brk(0x67e000) = 0x67e000
brk(0x680000) = 0x680000
close(3) = 0
rt_sigaction(SIGINT, {sa_handler=SIG_DFL, sa_mask=[RT_68 RT_69 RT_73 RT_74 RT_75 RT_76 RT_79 RT_80 RT_82 RT_85 RT_88 RT_89 RT_90 RT_91 RT_93 RT_94 RT_95], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0}, {sa_handler=0x400ea1, sa_mask=[RT_67 RT_68 RT_72 RT_73 RT_75 RT_76 RT_77 RT_83 RT_84 RT_85 RT_88 RT_89 RT_90 RT_91 RT_93 RT_94 RT_95], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0}, 16) = 0
exit_group(0) = ?
+++ exited with 0 +++
61行的返回值是 -1 EAGAIN (Resource temporarily unavailable);这样就足够了
发送超时
发送超时没有生效的原因在于…发送并没有超时,虽然没有被接收,但是发送确实是没有超时的