2013-11-11 4 views
0

Я пишу клиент-серверное приложение на Java так, чтобы клиент и сервер могли взаимодействовать друг с другом через сокет UDP, пинг-понг через сокет TCP и пользователи (клиенты) могли общаться друг с другом через сокеты TCP.Java-клиент смешанных функций TCP-и-UDP

У меня есть два отдельных потока TCP и UDP. У меня есть функции TCP и UDP для подключенного сервера (просто начав потоки TCP и UDP). Но как это сделать для клиента?

Я прошел через следующие страницы здесь:

1) Этот парень имеет TCP и UDP выделяемый для двух отдельных клиентов: Java TCP and UDP echo in one server

2) Нить Can two applications listen to the same port? предполагает, что я не могу использовать оба TCP и UDP для одного и того же номера порта одновременно для одного и того же клиента. Что подводит нас к ...

3) ... эту страницу: Listening for TCP and UDP requests on the same port. Однако он не предлагает ничего о том, как реализовать клиента. Кроме того, у него есть поток, а не клиент (странный), получающий пакеты и отправляющий их на сервер.

Я путешествовал по Сети (в частности, Google) и ничего не мог придумать. Я считаю, что очень немногие, если таковые имеются, рассмотрели этот вопрос.

Итак, опять же, мой вопрос: как я могу использовать функции TCP и UDP в клиенте? Я хочу, чтобы сервер мог подключаться к клиенту через сокеты TCP и UDP и использовать TCP между клиентами. Я не знаю, что делать дальше.

Любая помощь приветствуется. Заранее спасибо.

===========================================

Вот мой код клиента в его нынешнем виде:

 String hostName = args[0]; 
     int portNumber = Integer.parseInt(args[1]); 

     MulticastSocket udpSocket = new MulticastSocket(4446); 
     InetAddress address = InetAddress.getByName("230.0.0.1"); 
     udpSocket.joinGroup(address); 

     DatagramPacket packet; 

     // UDP: get a few quotes 
     for (int i = 0; i < 5; i++) { 

      byte[] buf = new byte[256]; 
      packet = new DatagramPacket(buf, buf.length); 
      udpSocket.receive(packet); 

      String received = new String(packet.getData(), 0, packet.getLength()); 
      System.out.println("Quote of the Moment: " + received); 
     } 

     udpSocket.leaveGroup(address); 
     udpSocket.close(); 

     // TCP 

     try (
      Socket tcpSocket = new Socket(hostName, portNumber); 
      PrintWriter out = new PrintWriter(tcpSocket.getOutputStream(), true); 
      BufferedReader in = new BufferedReader(
       new InputStreamReader(tcpSocket.getInputStream())); 
     ) { 
      BufferedReader stdIn = 
       new BufferedReader(new InputStreamReader(System.in)); 
      String fromServer; 
      String fromUser; 

      // AS LONG AS server and client are interacting: 
      while ((fromServer = in.readLine()) != null) { 
       System.out.println(fromServer); 
       if (fromServer.equals("Bye.")) 
        break; 

       fromUser = stdIn.readLine(); 
       if (fromUser != null) { 
        //System.out.println(fromUser); 
        out.println(fromUser); 
       } 
      } 
     } catch (UnknownHostException e) { 
      System.err.println("Unknown host: " + hostName); 
      System.exit(1); 
     } catch (IOException e) { 
      System.err.println("Unable to find I/O for connection to " + 
       hostName); 
      System.exit(1); 
     } 

в этом случае клиент получает дейтаграммы должным образом в UDP-соединения, а затем переходит к функциональности TCP, как и ожидалось. Две проблемы:

1) Сервер не может выйти из цикла прослушивания после ввода правильного ввода (я жестко запрограммирован в команде «exit»).

2) Сервер и клиент будут поддерживать соединение UDP только один раз перед переключением на TCP.

+0

В потоке, который вы цитируете для (2), не говорится, что вы не можете использовать один и тот же порт для TCP и UDP где бы я ни видел. Это даже не об этом. Любой источник, который говорит, что это неправильно. Ты можешь. Остальная часть вашего вопроса слишком широка, и на нем слишком много кода, на который нужно ответить. Пожалуйста, уменьшите его до управляемого размера и ответного вопроса. – EJP

+0

@EJP: (2) четко заявляет, что «для TCP, нет. У вас может быть только одно приложение, прослушивающее один порт за один раз». В ближайшее время изменит размер моего сообщения. Кроме того, если вопрос слишком широк, что нужно указать? – Andrei

+0

Это явно не означает, что вы не можете иметь TCP и UDP-сокет, привязанные к одному и тому же порту одновременно. Уверяю вас, это возможно, так как вы сами увидите, когда на самом деле попробуете. – EJP

ответ

3

У меня возникли проблемы идентификации актуальный вопрос здесь, но:

2) Резьба два приложения слушать тот же порт? предполагает, что я не могу одновременно использовать TCP и UDP для одного и того же номера порта для одного и того же клиента.

Это не говорит ничего подобного. В нем говорится, что у вас не может быть двух сокетов TCP, связанных с одним и тем же портом. В любом случае, дело в том, что вы можете.

Что приводит нас к ...

3) ... эта страница: Прослушивание TCP и UDP запросов на тот же порт.

И есть встречный пример, который доказывает точку.

Однако он не предлагает ничего о том, как реализовать клиента.

Такие как? Вам нужно только создать сокет TCP или UDP и либо подключить сокет TCP к удаленному IP-порту, либо просто использовать сокет UDP для отправки на этот IP-порт. Я не понимаю, в чем проблема.

Кроме того, у него есть нить, а не клиент (странный), получающий пакеты и отправляющие их на сервер.

Таким образом, поток является клиентом. Ничего странного в этом нет. Просто поднимите код и поместите его в программу. Voila: клиентская программа.

Как я могу заставить сервер прослушивать как TCP, так и UDP-запросы от одного и того же клиента?

Просто создайте новый ServerSocket(port) для TCP и UDP для new DatagramSocket(port) и есть поток прослушивания каждого. Поток TCP должен зацикливаться на вызове accept() и порождать новый поток за принятый Socket; поток UDP может просто зацикливаться на DatagramSocket.receive().

+0

Спасибо. Я последую за последним советом, который вы дали здесь. Извините, я новичок, поэтому я учусь. – Andrei

Смежные вопросы