Skip to content

Commit ecbc291

Browse files
committed
fix send timeout
1 parent 824032f commit ecbc291

2 files changed

Lines changed: 53 additions & 1 deletion

File tree

ljsocket.lua

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1523,6 +1523,14 @@ do
15231523
len, err, num = socket.send(self.fd, data, #data, flags)
15241524
end
15251525

1526+
if timeout_messages[num] then
1527+
if not self.blocking then
1528+
return nil, "tryagain", num
1529+
end
1530+
1531+
return nil, "timeout", num
1532+
end
1533+
15261534
if not len then return len, err, num end
15271535

15281536
if len > 0 then return len end

test/timeout_blocking.lua

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
local socket = require("ljsocket")
22
local test = require("test.gambarina")
33

4-
test('TCP client timeout blocking test', function()
4+
test('TCP client rcvtimeo timeout blocking test', function()
55
local sock = assert(socket.create("inet", "stream", "tcp"))
66
assert(sock:connect("httpbin.org", "http"))
77
assert(sock:send("GET /delay/10 HTTP/1.1\r\nHost: httpbin.org\r\n\r\n"))
@@ -11,4 +11,48 @@ test('TCP client timeout blocking test', function()
1111
error("expected timeout error, got data")
1212
end
1313
eq(err, "timeout")
14+
end)
15+
16+
test('TCP client sndtimeo blocking test', function()
17+
-- Create a server that accepts but never reads
18+
local server = assert(socket.create("inet", "stream", "tcp"))
19+
assert(server:set_option("reuseaddr", 1))
20+
assert(server:bind("127.0.0.1", "0")) -- bind to any available port
21+
assert(server:listen(1))
22+
23+
local _, port = assert(server:get_name())
24+
25+
-- Connect a client
26+
local client = assert(socket.create("inet", "stream", "tcp"))
27+
assert(client:connect("127.0.0.1", tostring(port)))
28+
29+
-- Accept the connection but don't read from it
30+
local accepted = assert(server:accept())
31+
32+
-- Set a short send timeout
33+
assert(client:set_option("sndtimeo", 0.25))
34+
35+
-- Try to send enough data to fill the send buffer
36+
-- This should eventually timeout when the buffer is full
37+
local large_data = string.rep("x", 65536)
38+
local timeout_occurred = false
39+
40+
for i = 1, 10000 do
41+
local bytes, err = client:send(large_data)
42+
if not bytes and err == "timeout" then
43+
timeout_occurred = true
44+
break
45+
end
46+
if not bytes then
47+
error("unexpected error: " .. tostring(err))
48+
end
49+
end
50+
51+
if not timeout_occurred then
52+
error("expected send timeout to occur")
53+
end
54+
55+
client:close()
56+
accepted:close()
57+
server:close()
1458
end)

0 commit comments

Comments
 (0)