1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
|
# -*- encoding: binary -*-
require_relative '../spec_helper'
require_relative '../fixtures/classes'
describe "BasicSocket#recv" do
before :each do
@server = TCPServer.new('127.0.0.1', 0)
@port = @server.addr[1]
end
after :each do
@server.close unless @server.closed?
ScratchPad.clear
end
it "receives a specified number of bytes of a message from another socket" do
t = Thread.new do
client = @server.accept
ScratchPad.record client.recv(10)
client.recv(1) # this recv is important
client.close
end
Thread.pass while t.status and t.status != "sleep"
t.status.should_not be_nil
socket = TCPSocket.new('127.0.0.1', @port)
socket.send('hello', 0)
socket.close
t.join
ScratchPad.recorded.should == 'hello'
end
ruby_version_is "3.3" do
it "returns nil on a closed stream socket" do
t = Thread.new do
client = @server.accept
packet = client.recv(10)
client.close
packet
end
Thread.pass while t.status and t.status != "sleep"
t.status.should_not be_nil
socket = TCPSocket.new('127.0.0.1', @port)
socket.close
t.value.should be_nil
end
end
platform_is_not :solaris do
it "accepts flags to specify unusual receiving behaviour" do
t = Thread.new do
client = @server.accept
# in-band data (TCP), doesn't receive the flag.
ScratchPad.record client.recv(10)
# this recv is important (TODO: explain)
client.recv(10)
client.close
end
Thread.pass while t.status and t.status != "sleep"
t.status.should_not be_nil
socket = TCPSocket.new('127.0.0.1', @port)
socket.send('helloU', Socket::MSG_OOB)
socket.shutdown(1)
t.join
socket.close
ScratchPad.recorded.should == 'hello'
end
end
it "gets lines delimited with a custom separator" do
t = Thread.new do
client = @server.accept
ScratchPad.record client.gets("\377")
# this call is important (TODO: explain)
client.gets(nil)
client.close
end
Thread.pass while t.status and t.status != "sleep"
t.status.should_not be_nil
socket = TCPSocket.new('127.0.0.1', @port)
socket.write("firstline\377secondline\377")
socket.close
t.join
ScratchPad.recorded.should == "firstline\377"
end
it "allows an output buffer as third argument" do
socket = TCPSocket.new('127.0.0.1', @port)
socket.write("data")
client = @server.accept
buf = "foo"
begin
client.recv(4, 0, buf)
ensure
client.close
end
buf.should == "data"
socket.close
end
end
describe 'BasicSocket#recv' do
SocketSpecs.each_ip_protocol do |family, ip_address|
before do
@server = Socket.new(family, :DGRAM)
@client = Socket.new(family, :DGRAM)
end
after do
@client.close
@server.close
end
describe 'using an unbound socket' do
it 'blocks the caller' do
-> { @server.recv(4) }.should block_caller
end
end
describe 'using a bound socket' do
before do
@server.bind(Socket.sockaddr_in(0, ip_address))
end
describe 'without any data available' do
it 'blocks the caller' do
-> { @server.recv(4) }.should block_caller
end
end
describe 'with data available' do
before do
@client.connect(@server.getsockname)
end
it 'reads the given amount of bytes' do
@client.write('hello')
@server.recv(2).should == 'he'
end
it 'reads the given amount of bytes when it exceeds the data size' do
@client.write('he')
@server.recv(6).should == 'he'
end
it 'blocks the caller when called twice without new data being available' do
@client.write('hello')
@server.recv(2).should == 'he'
-> { @server.recv(4) }.should block_caller
end
it 'takes a peek at the data when using the MSG_PEEK flag' do
@client.write('hello')
@server.recv(2, Socket::MSG_PEEK).should == 'he'
@server.recv(2).should == 'he'
end
end
end
end
end
|