Class: SFML::Network::TcpSocket

Inherits:
Object
  • Object
show all
Defined in:
lib/sfml/network/tcp_socket.rb

Overview

A TCP client socket. Connect to a server, send/receive bytes, disconnect.

sock = SFML::Network::TcpSocket.new
case sock.connect(SFML::Network::IpAddress::LOCALHOST, port: 8080)
when :done then ...
end

sock.send("hello")
status, bytes = sock.receive(max: 1024)

By default sockets are blocking; set socket.blocking = false for non-blocking polling, where send/receive may return :not_ready.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize ⇒ TcpSocket

Returns a new instance of TcpSocket.

Raises:



17
18
19
20
21
# File 'lib/sfml/network/tcp_socket.rb', line 17

def initialize
  ptr = C::Network.sfTcpSocket_create
  raise NetworkError, "sfTcpSocket_create returned NULL" if ptr.null?
  @handle = FFI::AutoPointer.new(ptr, C::Network.method(:sfTcpSocket_destroy))
end

Instance Attribute Details

#handle ⇒ Object (readonly)

:nodoc:



97
98
99
# File 'lib/sfml/network/tcp_socket.rb', line 97

def handle
  @handle
end

Instance Method Details

#blocking=(value) ⇒ Object

Set the blocking.



83
84
85
# File 'lib/sfml/network/tcp_socket.rb', line 83

def blocking=(value)
  C::Network.sfTcpSocket_setBlocking(@handle, value ? true : false)
end

#blocking? ⇒ Boolean

true if blocking.

Returns:

  • (Boolean)


80
# File 'lib/sfml/network/tcp_socket.rb', line 80

def blocking? = C::Network.sfTcpSocket_isBlocking(@handle)

#connect(address, port:, timeout: SFML::Time.zero) ⇒ Object

Open a connection. Returns one of the SOCKET_STATUSES symbols (:done, :not_ready, :disconnected, :error). timeout is a SFML::Time; SFML::Time.zero (default) blocks forever.



26
27
28
29
30
# File 'lib/sfml/network/tcp_socket.rb', line 26

def connect(address, port:, timeout: SFML::Time.zero)
  addr = address.is_a?(IpAddress) ? address : IpAddress.from_string(address)
  code = C::Network.sfTcpSocket_connect(@handle, addr.struct, Integer(port), timeout.to_native)
  C::Network::STATUSES[code]
end

#disconnect ⇒ Object

Returns the disconnect.



33
34
35
36
# File 'lib/sfml/network/tcp_socket.rb', line 33

def disconnect
  C::Network.sfTcpSocket_disconnect(@handle)
  self
end

#local_port ⇒ Object

Returns the local port.



88
89
# File 'lib/sfml/network/tcp_socket.rb', line 88

def local_port  = C::Network.sfTcpSocket_getLocalPort(@handle)
# Returns the remote port.

#receive(max: 4096) ⇒ Object

Read up to max bytes. Returns [status, data] — data is a binary String when status is :done, nil otherwise.



49
50
51
52
53
54
55
56
57
58
# File 'lib/sfml/network/tcp_socket.rb', line 49

def receive(max: 4096)
  buf      = FFI::MemoryPointer.new(:uint8, Integer(max))
  received = FFI::MemoryPointer.new(:size_t)
  code = C::Network.sfTcpSocket_receive(@handle, buf, Integer(max), received)
  status = C::Network::STATUSES[code]

  return [status, nil] unless status == :done
  n = received.read(:size_t)
  [status, buf.read_bytes(n)]
end

#receive_packet ⇒ Object

Receive into a fresh Packet. Returns [status, packet]; the packet is nil for non-:done statuses.



72
73
74
75
76
77
# File 'lib/sfml/network/tcp_socket.rb', line 72

def receive_packet
  pkt  = Packet.new
  code = C::Network.sfTcpSocket_receivePacket(@handle, pkt.handle)
  status = C::Network::STATUSES[code]
  [status, status == :done ? pkt : nil]
end

#remote_address ⇒ Object

Returns the remote address.



93
94
95
# File 'lib/sfml/network/tcp_socket.rb', line 93

def remote_address
  IpAddress.wrap(C::Network.sfTcpSocket_getRemoteAddress(@handle))
end

#remote_port ⇒ Object

Returns the remote port.



90
# File 'lib/sfml/network/tcp_socket.rb', line 90

def remote_port = C::Network.sfTcpSocket_getRemotePort(@handle)

#send(data) ⇒ Object

Returns the send.



39
40
41
42
43
44
45
# File 'lib/sfml/network/tcp_socket.rb', line 39

def send(data)
  bytes = data.to_s
  buf   = FFI::MemoryPointer.new(:uint8, bytes.bytesize)
  buf.write_bytes(bytes)
  code = C::Network.sfTcpSocket_send(@handle, buf, bytes.bytesize)
  C::Network::STATUSES[code]
end

#send_packet(packet) ⇒ Object

Send a structured SFML::Network::Packet. CSFML frames the wire bytes with a length prefix so the peer's receive_packet always gets a whole packet (no need to handle TCP boundary fragments at the Ruby layer).

Raises:

  • (ArgumentError)


64
65
66
67
68
# File 'lib/sfml/network/tcp_socket.rb', line 64

def send_packet(packet)
  raise ArgumentError, "expected SFML::Network::Packet" unless packet.is_a?(Packet)
  code = C::Network.sfTcpSocket_sendPacket(@handle, packet.handle)
  C::Network::STATUSES[code]
end