Question: Trying to figure out how to send/read data through socket. On remote server I create new `netcat -l 4444` and from local send text data `echo "test" | netcat remote.host 4444`. This is always works fine.

Trying to reproduce:

```
require "socket"

HOST = "remote.host"
PORT = 4444

ch_request = Channel(String).new
ch_response = Channel(String).new

spawn do
  socket = TCPSocket.new(HOST, PORT)
  loop do
    select
    when request = ch_request.receive
      socket << request
      socket.flush
    end

    if response = socket.gets
      ch_response.send response
    end
  end
end

sleep 0.1

ch_request.send "hello"

loop do
  select
  when response = ch_response.receive
    pp response
  end
end

```

In my dream I send data to channel, read it from first loop then send to socket. The same way but reverse order need for read it from second loop.

On practice this is not happens. On local after connect I got "test" and can't send back anything. On remote I can send to local but on local got only empty string once and nothing more after.

What mean this behavior and how to achieve planned?

Answer: 
You didn't show this, but I suppose you have a second implementation using `TCPServer` for the `netcat -l` equivalent.

You need to use separate fibers for reading/writing to the socket and the channel. It's a bit hard to judge what exactly happens without seeing the server, but I suppose you end up in a deadlock where both sides are waiting on input of the other side or user, but cannot proceed to actually send or read anything. In other words you interlocked the sending/receiving part, requiring the other side to carefully react and interplay so to not lock up the client. This is obviously a brittle approach.

Instead you should make sure any fiber does not do more than one operation in a loop. One receives from the socket and forwards that to a channel, the second one receives from a channel and forwards that to the socket, the third one receives from the reader side channel and prints or does whatever you want to do the data and the last one fills the sender channel. This way no operation can block one of the others. Of course one of those fibers should simply be the main program one.

In the server you additionally need one fiber that accepts the client connections and spawns the sender and receiver loops for each.

Finally note that a `select` statement with a single `when` branch has no effect, you can make the call directly. `select` is useful if you need to read or write to multiple channels concurrently in the same fiber, so for example if you would have multiple channels providing data to be send out to a socket, you would use `select` to not have the messages be corrupted by two fibers writing to the same socket at the same time. An additional usecase for `select` is to send or receive from a channel with a timeout.
Who is looking for an answer to similar questions. The final result what I wanted looks like this:

```
# Open socket for simulate remote server: `netcat -v -4 -l 4444`

require "socket"

HOST = "remote.host"
PORT = 4444

# JFYI: In real life this packed into class and I use class variable instead consts.
TUBE_REQUEST  = Channel(String).new
TUBE_RESPONSE = Channel(String).new

SOCKET = TCPSocket.new(HOST, PORT)

spawn do
  until SOCKET.closed?
    if request = TUBE_REQUEST.receive
      SOCKET << request
      SOCKET.flush
    end
  end
end

spawn do
  until SOCKET.closed?
    if response = SOCKET.gets
      TUBE_RESPONSE.send response
    end
  end
end

sleep 0.1

def receive_response
  TUBE_RESPONSE.receive
end

def send(message, wait_for_response = true)
  TUBE_REQUEST.send message
  receive_response if wait_for_response
end

send("command with response")
send("command with new line and response\n")
send("command without new line and response", false)

```

It will send each command and wait for answer (except the last) from remote and then call the next command.