簡體   English   中英

如何在與套接字服務器相同的計算機(IP)上運行套接字客戶端?

[英]How to run a socket client on the same computer (IP) as a socket server?

我進行了一個簡單的聊天,如果在一個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();
            }
        }
    }

}

178.165.87.221是服務器計算機的本地IP嗎? 本地,就像在終端上運行ipconfigifconfig ,您將看到此ip。如果要在同一台計算機上同時運行服務器和客戶端,則客戶端應使用服務器的本地IP,

如果您不知道本地IP,則可以使用localhost127.0.0.1

因此客戶端代碼應為以下代碼之一:

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

要么

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

要么

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防火牆允許/轉發聊天系統端口到服務器計算機的本地IP

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM