1
votes

server.rb

require 'socket'
Socket.tcp_server_loop(6666) do |connection|
  while data = connection.read(1024 * 16) do
    if data == 'hello'
      connection.write('hi hi hi hi hi')
    end
  end
  connection.close
end

client.rb require 'socket' require 'io/console'

client = TCPSocket.new('localhost', 6666)
client.write('hello')
client.flush
# client.close_write
# client.close_write
# client.fdatasync
# client.fsync

data = client.read
puts data

# client.open
# client.write('hello')
# puts client.read

I want to reuse the socke, so I don't want to close it.

But if I don't send client.close_write , it not work, cann't read server data. if client.close_write the socket closed, and it will not write data to server any more.

I want to know how to tell EOF and don't close the socket? client.fdatasync => in `fdatasync': Operation not supported (Errno::ENOTSUP)

client.fsync => in `fsync': Operation not supported (Errno::ENOTSUP)

I thought the fdatasync and fsync maybe the method to tell EOF, but they not work.

c language has a method to do that: ssize_t send(int sockfd, const void *buff, size_t nbytes, int flags) the nbytes tell the server data size. there is no method like this in ruby.

1

1 Answers

2
votes

c language has a method to do that: ssize_t send(int sockfd, const void *buff, size_t nbytes, int flags) the nbytes tell the server data size.

C does not have a method to do that. nbytes in send tells send how much of the buff to send, and does not communicate an EOF to the other side. Ruby is equivalent: there is no EOF in a socket other than at closing. EOF is a condition (a flag that a stream has reached its end); it does not typically exist as something that is transmittable in and of itself.

Alternately, you can send a size that your content will be: that is the purpose of Content-Length header in HTTP. A web server considers the request finished when it has received Content-Length bytes after body is begun. If the server also sends Content-Length in the response, then the client knows when the server is done without server breaking connection, and the connection can be reused. Another way of signifying an end is to have a marker that unambiguously signals an end. You can employ the EOT character (0x04), as long as you don't transmit any content that might contain it naturally (in general, OK with texts, not OK with binary data). If you are transmitting data that could include an EOT, you can encode them so that it becomes impossible (e.g. using Base64).