Почему сервер сокетов Ruby работает с другим клиентом сокетов Ruby, но не с клиентом сокетов C #? - PullRequest
0 голосов
/ 21 января 2019

Итак, у меня есть две программы на Ruby, они являются программами сокетов клиента и сервера и работают вместе, обмениваясь сообщениями.Но клиент C # не работает.Я даю MCVE, сначала клиент ruby.

#socketClient.rb
#With thanks to https://code.likeagirl.io/socket-programming-in-ruby-f714131336fd
require "socket"

while sum = $stdin.gets.chomp # Read lines from the socket
  socket = TCPSocket.open("localhost", 3000)

  #puts "Starting the Client..................."

  socket.puts sum
  while message = socket.gets # Read lines from the socket
    puts message.chomp
  end
  socket.close                    # Close the socket
end

#puts "Closing the Client..................."

и сервер

#simplestSocketServer.rb
#With thanks to https://code.likeagirl.io/socket-programming-in-ruby-f714131336fd

require "socket"

port = 3000
ipAddress = "127.0.0.1"
server = TCPServer.open(ipAddress, port) # Server would listen on port 3000
loop { # Servers run forever
puts "Starting the Server, accepting connections on port " + port.to_s + "..................."
client_connection = server.accept # Establish client connect connection
begin
    clientText = client_connection.gets.chomp
    puts clientText

    resp = "Acknowledged"
    client_connection.puts("#{clientText}" +  "#{resp}") # Send the answer to the client
    client_connection.puts("Closing the connection with #{client_connection}")
rescue Exception => getException
    puts "#{getException}"
end
client_connection.close      # Disconnect from the client
}

и консольную программу C #

using System;
using System.Net.Sockets;
using System.Text;


namespace SimplestCSharpRubySocketsClient
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                string ipAddress = "127.0.0.1";
                Int16 portNumber = 3000;

                TcpClient _client; _client = new TcpClient();
                _client.Connect(ipAddress, portNumber);

                System.Console.WriteLine("we have connected, seemingly ...");

                NetworkStream stream;

                stream = _client.GetStream();

                Byte[] sendBytes = Encoding.UTF8.GetBytes("some text");

                System.Console.WriteLine("writing and flushing some bytes ...");
                stream.Write(sendBytes, 0, sendBytes.Length);
                stream.Flush();

                Byte[] recvBytes = new byte[_client.ReceiveBufferSize];
                System.Console.WriteLine("_client.ReceiveBufferSize = " + _client.ReceiveBufferSize);  // <--- this prints 65536

                System.Console.WriteLine("waiting to read bytes ...");
                stream.Read(recvBytes, 0, recvBytes.Length); //<--- hangs here

                System.Console.WriteLine("comething came back ...");
                string result = Encoding.UTF8.GetString(recvBytes);
                string result2 = result.Substring(0, result.LastIndexOf("\r\n"));

                _client.Close();
                _client.Dispose();
                _client = null;
            }
            catch (Exception ex)
            {
                //TODO figure out a better error handler
                throw ex;
            }
        }
    }
}

Программа C # подключается и пишетбайты, но при поиске читать байты просто зависает.

И помните, что я запускаю консольную программу C # в Visual Studio с правами администратора.Две программы ruby ​​запускаются в своих отдельных окнах консоли Windows.

Сложив некоторые отзывы, я добавил еще одну строку на сервере ruby ​​для вывода clientText.И он ничего не печатает, предполагая, что сервер не получает байты полностью.Есть ли сигнал завершения, который требуется для отправки C #?

Заранее спасибо.

1 Ответ

0 голосов
/ 21 января 2019

Проблема здесь в том, что клиент C # не отправляет новую строку в конце строки, как это делает версия Ruby (socket.puts отправляет строку с новой строкой в ​​конце).

Если вы измените массив sendBytes для включения \n в полезную нагрузку следующим образом:

Byte[] sendBytes = Encoding.UTF8.GetBytes("some text\n");

вы увидите, что он печатает comething came back ... на консоли.

Новая строка необходима из-за следующего gets на сервере Ruby:

clientText = client_connection.gets.chomp
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...