【问题标题】:Java <-> C# Socket: cant receive messagesJava <-> C# Socket:无法接收消息
【发布时间】:2012-03-28 06:51:48
【问题描述】:

我需要在我自己编写的java 服务器和C# 客户端之间进行套接字通信,问题是C# 客户端无法从我的 java 服务器接收任何消息,但是向我的 java 服务器发送消息可以.

我的工作流程:

  1. Java:创建服务器
  2. Java:等待客户端连接
  3. c#:创建客户端
  4. c#:建立与服务器的连接
  5. c#:向服务器发送一条消息
  6. Java:收到消息
  7. java: 向 c# 客户端发送消息
  8. c#: 从服务器接收消息

Java 服务器代码:

public class Communicator {

   private int m_port;
   private Socket m_socket;
   private ServerSocket m_serverSocket;

   public Communicator(int port) {
        this.m_port = port;
        initConnection();
    }

    private void initConnection() {

        try {
            System.out.println("Creating Server");
            m_serverSocket = new ServerSocket(m_port);
            System.out.println("Waiting for client connection");
            m_socket = m_serverSocket.accept();
            System.out.println("Connection made");

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

   public String sendMsg(JSONMessage msg) {
        try {

     //get msg
     BufferedReader bufferedReader = new BufferedReader(
           new InputStreamReader(m_socket.getInputStream()));
     System.out.println("Waiting for msg...");
       String answer = bufferedReader.readLine();
       System.out.println("Received: " + answer);

       //send msg
       PrintWriter writer = new PrintWriter(m_socket.getOutputStream(),true);
       writer.print(msg.getMsg());
       System.out.println("Sending: " + msg.getMsg());

       writer.flush();

    } catch (IOException e) {
        e.printStackTrace();
    }

        return "";
    }

}

我的 C# 客户端代码:

class Communicator
    {
        private int m_port;
        private Thread mainThread;

        public Communicator(int port)
        {
            m_port = port;
            mainThread = new Thread(new ThreadStart(this.initConnection));
            mainThread.Start();
        }

        public void initConnection()
        {
            IPEndPoint ip = new IPEndPoint(IPAddress.Parse("127.0.0.1"), m_port);
            Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            try
            {
                Console.WriteLine("Trying to build connection");
                server.Connect(ip);
                Console.WriteLine("Connection successful");

                NetworkStream ns = new NetworkStream(server);
                StreamReader sr = new StreamReader(ns);
                StreamWriter sw = new StreamWriter(ns);
                string data;

                string welcome = "Hello";
                Console.WriteLine("Sending: " + welcome);
                sw.WriteLine(welcome);
                sw.Flush();

                Console.WriteLine("Receiving...");
                data = sr.ReadLine();
                // --> NEVER REACHING THIS POINT <---
                Console.WriteLine("Received: " + data);                                         

            }
            catch (SocketException e)
            {
                Console.WriteLine("Connection failed.");
                return;
            }

        }
    }

有人知道为什么它永远不会到达我的客户端代码 Console.WriteLine("Received: " + data); 吗?

我已经尝试过两边都等待。我没有收到任何异常或错误,所以我真的不知道我的问题出在哪里。

谢谢

【问题讨论】:

    标签: c# java sockets tcp message


    【解决方案1】:

    如果您的接收者期待 lines,您的发送者必须发送 lines。您的发件人不会发送线路,因此接收者会一直等待直到收到。

    为避免将来出现此类问题,您应该始终制作规范文档来解释您的协议的工作原理,最好是在字节级别。它应该指定协议是否包含消息,如果包含,发送者如何标记消息边界以及接收者如何识别它们。

    在这里,您的接收者通过查找行尾来识别消息边界。但是您的发件人不会用行尾标记邮件边界。所以接收者永远等待。

    如果您有协议规范,这将是显而易见的。将来,我强烈建议您花时间指定您实施的每个协议。

    【讨论】:

    • 更改为 writer.println(msg.getMsg());或在 C# 中使用 sr.Read 而不是 ReadLine。
    • 如果他使用sr.Read,他将根本无法识别消息边界。这取决于他在做什么,也可能无关紧要。
    • 如果Java服务器也有Java客户端,那么他需要更改C#客户端,而不是Java服务器。使用 JSON 应该相当直接地确定是否是有效的 JSON 消息。
    • 非常感谢,这不是最终的实现/协议,我想测试发送/接收是否以简单的方式工作,我从来没有使用过 c#,所以这是一个测试。我的目标是在我的 java 和我的 c# 程序之间发送 json 消息。
    • 如果您想保持简单,请使用规范。否则,很难分辨出什么坏了。有了规范,很简单:1)发件人是否遵循规范?如果没有,它已经坏了。 2) 收件人是否遵守规范?如果没有,它已经坏了。 3) 如果还是不行,说明规范有问题。 -- 如果没有规范,我们仍然不知道哪一方是错误的,因为我们不知道您是否有应用程序级消息,如果有,我们也不知道它们应该如何分隔。
    【解决方案2】:

    您需要使用添加新行的 println() 而不是 print()。在 Java 中,readLine 等待一个新行,我希望它在 C# 中做同样的事情。 println 也会自动刷新,所以你也不需要刷新。

    如果您打算多次使用此连接 mreo,则需要为连接保留 BufferedReader 和 PrintWriter。 (所以我建议您在创建/接受套接字后创建这些)为同一个套接字多次创建这些可能容易出错且令人困惑。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-07
      • 2016-05-27
      • 1970-01-01
      • 1970-01-01
      • 2017-06-18
      • 1970-01-01
      • 2017-09-04
      • 2012-11-29
      相关资源
      最近更新 更多