Указатель NULL
- это тот, который указывает на никуда. Когда вы разыскиваете указатель p
, вы говорите «дайте мне данные в месте, хранящемся в« p ». Когда p
является нулевым указателем, местоположение, хранящееся в p
, является nowhere
, вы говорите «Дайте мне данные в месте« нигде ». Очевидно, он не может этого сделать, поэтому он выбрасывает NULL pointer exception
.
В общем, это потому, что что-то не было правильно инициализировано.
Можно использовать выбор, чтобы видеть, можете ли Вы безопасно добираться от сокета, видеть следующую реализацию TCPServer, использующего эту технику.
require 'socket'
host, port = 'localhost', 7000
TCPServer.open(host, port) do |server|
while client = server.accept
readfds = true
got = nil
begin
readfds, writefds, exceptfds = select([client], nil, nil, 0.1)
p :r => readfds, :w => writefds, :e => exceptfds
if readfds
got = client.gets
p got
end
end while got
end
end
И здесь клиент, который пытается повредить сервер:
require 'socket'
host, port = 'localhost', 7000
TCPSocket.open(host, port) do |socket|
socket.puts "Hey there"
socket.write 'he'
socket.flush
socket.close
end
IO#closed? возвращает true, когда и средство чтения и устройство записи закрываются. В Вашем случае @sock.gets возвращает ноль, и затем Вы называете getcmd снова, и это работает в никогда конечном цикле. Можно или использовать выбор или закрыть сокет, когда получает ноль возвратов.
Если Вы верите rdoc для рубиновых сокетов, они не реализуют gets
. Это приводит меня верить, добирается, обеспечивается более высоким уровнем абстракции (возможно, библиотеки IO?) и вероятно не знает об определенных для сокета вещах как 'закрытое соединение'.
Попытайтесь использовать recvfrom
вместо gets