Java <-> C # Socket: не могу получать сообщения - PullRequest
4 голосов
/ 28 марта 2012

Мне нужна связь через сокет между моим собственным письменным java сервером и C# клиентом, проблема в том, что клиент C# не может получать сообщения от моего java-сервера, но отправка сообщений на мой java-сервер работает .

мой рабочий процесс:

  1. Java: Создать сервер
  2. Java: ожидание соединения с клиентом
  3. c #: создание клиента
  4. c #: установить соединение с сервером
  5. c #: отправить сообщение на сервер
  6. Java: получено сообщение
  7. Java: отправка сообщения клиенту c #
  8. c #: получение сообщения от сервера <- это точка, в которой клиент ожидает сообщения, но никогда не получает. </li>

Код 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);?

Я уже пробовал с ожиданиями с обеих сторон. Я не получаю никаких исключений или ошибок, поэтому у меня нет идеи, где моя проблема.

Спасибо

Ответы [ 2 ]

4 голосов
/ 28 марта 2012

Если ваш получатель ожидает строк , ваш отправитель должен отправить строк .Ваш отправитель не отправляет линии, поэтому получатель ждет его до тех пор, пока не получит его.

Чтобы избежать подобных проблем в будущем, вы всегда должны составлять документ спецификации, который объясняет, как работает ваш протокол, в идеале науровень байтов.Следует указать, содержит ли протокол сообщения и, если да, то, как отправитель помечает границы сообщений и как их идентифицирует получатель.

Здесь ваш получатель идентифицирует границы сообщений, просматривая окончания строк.Но ваш отправитель не помечает границы сообщений окончаниями строк.Таким образом, получатель ждет вечно.

Если бы у вас была спецификация протокола, это было бы очевидно.В будущем я настоятельно призываю вас потратить время на указание каждого протокола, который вы реализуете.

2 голосов
/ 28 марта 2012

Вам нужно использовать println (), которая добавляет новую строку вместо print (). В Java readLine ждет новой строки, и я ожидаю, что она сделает то же самое в C #. Также println будет автоматически очищаться, поэтому вам также не нужно очищать.

Если вы собираетесь использовать это соединение более одного раза, вам нужно сохранить BufferedReader и PrintWriter для этого соединения. (Поэтому я предлагаю вам создать их после того, как сокет будет создан / принят). Многократное создание одного и того же сокета может привести к ошибкам и сбить с толку.

...