2017-08-03 63 views
0

我做了一個簡單的聊天,它按照設計工作,如果在一個IP上運行服務器,而在另一個IP上運行客戶端。此聊天適用於網絡。問題是 - 當我嘗試在我的計算機上運行服務器時,我的計算機上的客戶端無法運行。但是如果有其他IP的人嘗試連接到服務器 - 一切正常。可能是什麼問題?如何在與套接字服務器相同的計算機(IP)上運行套接字客戶端?

服務器:

/** 
* Created by rnd on 7/4/2017. 
*/ 

import java.io.*; 
import java.net.*; 
import java.nio.charset.Charset; 
import java.nio.charset.StandardCharsets; 
import java.util.*; 

public class VerySimpleChatServer { 

    ArrayList clientOutputStreams; 
    ArrayList<String> m_history; 


    public static void main (String[] args) { 
     new VerySimpleChatServer().go(); 
    } 

    public void go() { 
     clientOutputStreams = new ArrayList(); 
     m_history = new ArrayList<String>(); 
     try { 
      ServerSocket serverSock = new ServerSocket(10001); 

      while(true) { 
       Socket clientSocket = serverSock.accept(); 

       Charset charset = StandardCharsets.UTF_8; 
       OutputStreamWriter osw = new OutputStreamWriter(clientSocket.getOutputStream(), charset); 
       PrintWriter writer = new PrintWriter(new BufferedWriter(osw)); 

//    PrintWriter writer = new PrintWriter(clientSocket.getOutputStream()); 

       writer.println("Welcome to the chat 7 kids.... Семеро Козлят"); 
       writer.flush(); 

       clientOutputStreams.add(writer); 
       Thread t = new Thread(new ClientHandler(clientSocket)); 
       t.start() ; 
       System.out.println("got a connection"); 
      } 
     } catch(Exception ex) { 
      ex.printStackTrace(); 
     } 
    } // Закрываем go 


public class ClientHandler implements Runnable { 

    BufferedReader reader; 
    Socket sock; 

    public ClientHandler(Socket clientSocket) { 

     try { 
      sock = clientSocket; 
      InputStreamReader isReader = new InputStreamReader(sock.getInputStream(), StandardCharsets.UTF_8); 
      reader = new BufferedReader(isReader); 
     } catch(Exception ex) {ex.printStackTrace();} 

    } // Закрываем конструктор 

    public void run() { 
     String message; 

     tellHistory(m_history); 

     try { 

      while ((message = reader.readLine()) != null) { 
       System.out.println("read " + message); 
       m_history.add(message); 

       tellEveryone(message); 
      } // Закрываем while 
     } catch(Exception ex) {ex.printStackTrace();} 
    } // Закрываем run 
} // Закрываем вложенный класс 




    public void tellEveryone(String message) { 
     Iterator it = clientOutputStreams.iterator(); 
     while(it.hasNext()) { 
      try { 
       PrintWriter writer = (PrintWriter) it.next(); 
       writer.println(message); 
       writer.flush(); 
      } catch(Exception ex) { 
       ex.printStackTrace(); 
      } 
     } // Конец цикла while 
    } // Закрываем tellEveryone 

    public void tellHistory(ArrayList<String> history){ 


      try { 
       PrintWriter writer1 = (PrintWriter) clientOutputStreams.get(clientOutputStreams.size() - 1); 

       for (int i = 0; i < history.size(); i++) { 
        writer1.println(history.get(i)); 
       } 
       //Идея в том, что бы вызывать историю только для последнего PrintWriter 
       //может быть getsize поставить вместо i - writer1.println(history.get(history.size())); 

       writer1.flush(); 
      } catch(Exception ex) { 
       ex.printStackTrace(); 
      } 


    } 

} // Закрываем класс 

客戶:

/** 
* Created by rnd on 7/4/2017. 
*/ 

import java.io.*; 
import java.net.*; 
import java.nio.charset.Charset; 
import java.nio.charset.StandardCharsets; 
import java.util.*; 
import javax.swing.*; 
import java.awt.*; 
import java.awt.event.*; 


public class SimpleChatClient { 

    JTextArea incoming; 
    JTextField outgoing; 
    JTextField name; 
    BufferedReader reader; 
    PrintWriter writer; 
    Socket sock; 
    String Myname; 


    public static void main(String[] args) { 
     SimpleChatClient client = new SimpleChatClient(); 
     client.go();} 

    public void go(){ 
     JFrame frame = new JFrame("Ludicrously Simple Chat Client"); 
     JPanel mainPanel = new JPanel(); 
     incoming = new JTextArea(15,50); 
     incoming.setLineWrap(true); 
     incoming. setWrapStyleWord (true) ; 
     incoming.setEditable(false); 
     JScrollPane qScroller = new JScrollPane(incoming); 
     qScroller. setVerticalScrollBarPolicy (ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS) ; 
     qScroller. setHorizontalScrollBarPolicy (ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS) ; 
     outgoing = new JTextField(20); 
     name = new JTextField(5); 
     JButton sendButton = new JButton("Send") ; 
     JLabel label1 = new JLabel("name"); 

     sendButton.addActionListener(new SendButtonListener()); 
     mainPanel.add(qScroller); 
     mainPanel.add(label1); 
     mainPanel.add(name); 
     mainPanel.add(outgoing); 
     mainPanel.add(sendButton); 

     setUpNetworking(); 

     Thread readerThread = new Thread(new IncomingReader()); 
     readerThread.start(); 

     frame.getContentPane().add(BorderLayout.CENTER, mainPanel); 
     frame.setSize(800,500); 
     frame.setVisible(true); 

    } 

    private void setUpNetworking() { 
     try { 
      sock = new Socket("178.165.87.221", 10001); 
//   sock = new Socket("127.0.0.1", 10001); 
      InputStreamReader streamReader = new InputStreamReader(sock.getInputStream(), StandardCharsets.UTF_8); 
      reader = new BufferedReader(streamReader); 


      Charset charset = StandardCharsets.UTF_8; 
      OutputStreamWriter osw = new OutputStreamWriter(sock.getOutputStream(), charset); 
      writer = new PrintWriter(new BufferedWriter(osw)); 

//   writer = new PrintWriter(sock.getOutputStream()); 
      System.out.println("networking established"); 
     } catch (IOException ex) { 
       ex.printStackTrace();} 
    } 

    public class SendButtonListener implements ActionListener { 
     public void actionPerformed (ActionEvent ev) { 
      try { 
       Myname = name.getText(); 
       writer.println(Myname + ": " + outgoing.getText()); 
       writer.flush(); 

      } catch(Exception ex) { 
       ex.printStackTrace(); 
      } 
      outgoing. setText ("") ; 
        outgoing.requestFocus() ;} 
    } 

    public class IncomingReader implements Runnable{ 
     @Override 
     public void run() { 
      String message; 

      try{ 
       while((message=reader.readLine())!=null){ 
        System.out.println("read " + message); 
        incoming.append(message + "\n"); 
       } 

      } catch (Exception ex) { 
       ex.printStackTrace(); 
      } 
     } 
    } 

} 
+0

你監聽所有網絡接口的本地IP? –

+0

是這個'178.165.87.221'服務器機器的本地IP地址?本地,如果你在終端中運行'ipconfig'或'ifconfig',你會看到這個ip – Yazan

+0

我已經取消註釋'sock = new Socket(「127.0.0.1」,10001);'行和客戶端運行時沒有任何異常。確切地說,是 – eparvan

回答

3

是這個178.165.87.221服務器計算機的本地IP?本地,就好像你在終端上運行ipconfigifconfig你會看到這個ip ,,,如果你想在同一臺機器上運行服務器和客戶端,客戶端應該使用服務器的本地IP,如果你不想「知道本地IP,您可以使用localhost127.0.0.1

所以客戶端代碼應該是其中的一個:

sock = new Socket("127.0.0.1", 10001); //localhost alias 

OR

sock = new Socket("localhost", 10001); //localhost alias 

OR

sock = new Socket("192.168.100.10", 10001); // local IP [machine local IP might be something else, this is only an example] 

注: 178.165.87.221看起來像一個真實的IP,如果你想在客戶端使用,同時在同一臺機器在服務器上,您可能需要配置您的路由器/網絡防火牆/ OS防火牆允許/向前聊天系統端口到服務器計算機

+1

。這個問題意味着OP出於某種原因無法連接到他自己的公共IP地址。 – EJP

+1

當使用localhost/127.0.0.1作爲Server IP時,上述代碼適用於我。我認爲這更多的是路由/網絡問題,而不是代碼問題。 – DrHopfen

+0

謝謝!這就是我想聽到的:「OP無法從內部連接到他自己的公共IP地址」。所以我只需創建一個具有本地IP的獨立客戶端即可從同一臺計算機連接服務器。 – SergeiK

相關問題