代码之家  ›  专栏  ›  技术社区  ›  S Meaden

为什么Ruby Sockets服务器与其他Ruby Sockets客户机一起工作,而不是与C Sockets客户机一起工作?

  •  1
  • S Meaden  · 技术社区  · 6 年前

    所以我有两个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程序连接并写入字节,但当读取字节时,它只是挂起。

    请注意,我正在Visual Studio中运行具有管理权限的C控制台程序。这两个Ruby程序在各自独立的Windows控制台窗口中运行。

    在一些反馈中,我在Ruby服务器中添加了另一行来输出客户机文本。它什么也不打印,表明服务器没有完全接收字节。是否需要C发送终止信号?

    事先谢谢。

    1 回复  |  直到 6 年前
        1
  •  3
  •   Jyrki    6 年前

    这里的问题是C客户机不会像Ruby版本那样在字符串末尾发送换行符。( socket.puts 发送末尾有换行符的字符串)。

    如果你改变你的 sendBytes 要包含的数组 \n 在这样的有效载荷中:

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

    你会看到它印出来的 comething came back ... 在控制台上。

    由于以下原因,需要换行 gets 在Ruby服务器中:

    clientText = client_connection.gets.chomp