Как заставить этот сервер работать на нескольких компьютерах в сети - PullRequest
0 голосов
/ 14 июля 2020
import java.net.*; 
import java.io.*; 
import java.util.*; 
public class GroupChat 
{ 
    private static final String TERMINATE = "Exit"; 
    static String name; 
    static volatile boolean finished = false; 
    public static void main(String[] args) 
    { 
        if (args.length != 2) 
            System.out.println("Two arguments required: <multicast-host> <port-number>"); 
        else
        { 
            try
            { 
                InetAddress group = InetAddress.getByName(args[0]); 
                int port = Integer.parseInt(args[1]); 
                Scanner sc = new Scanner(System.in); 
                System.out.print("Enter your name: "); 
                name = sc.nextLine(); 
                MulticastSocket socket = new MulticastSocket(port); 
              
                // Since we are deploying 
                socket.setTimeToLive(0); 
                //this on localhost only (For a subnet set it as 1) 
                  
                socket.joinGroup(group); 
                Thread t = new Thread(new
                ReadThread(socket,group,port)); 
              
                // Spawn a thread for reading messages 
                t.start();  
                  
                // sent to the current group 
                System.out.println("Start typing messages...\n"); 
                while(true) 
                { 
                    String message; 
                    message = sc.nextLine(); 
                    if(message.equalsIgnoreCase(GroupChat.TERMINATE)) 
                    { 
                        finished = true; 
                        socket.leaveGroup(group); 
                        socket.close(); 
                        break; 
                    } 
                    message = name + ": " + message; 
                    byte[] buffer = message.getBytes(); 
                    DatagramPacket datagram = new
                    DatagramPacket(buffer,buffer.length,group,port); 
                    socket.send(datagram); 
                } 
            } 
            catch(SocketException se) 
            { 
                System.out.println("Error creating socket"); 
                se.printStackTrace(); 
            } 
            catch(IOException ie) 
            { 
                System.out.println("Error reading/writing from/to socket"); 
                ie.printStackTrace(); 
            } 
        } 
    } 
} 
class ReadThread implements Runnable 
{ 
    private MulticastSocket socket; 
    private InetAddress group; 
    private int port; 
    private static final int MAX_LEN = 1000; 
    ReadThread(MulticastSocket socket,InetAddress group,int port) 
    { 
        this.socket = socket; 
        this.group = group; 
        this.port = port; 
    } 
      
    @Override
    public void run() 
    { 
        while(!GroupChat.finished) 
        { 
                byte[] buffer = new byte[ReadThread.MAX_LEN]; 
                DatagramPacket datagram = new
                DatagramPacket(buffer,buffer.length,group,port); 
                String message; 
            try
            { 
                socket.receive(datagram); 
                message = new
                String(buffer,0,datagram.getLength(),"UTF-8"); 
                if(!message.startsWith(GroupChat.name)) 
                    System.out.println(message); 
            } 
            catch(IOException e) 
            { 
                System.out.println("Socket closed!"); 
            } 
        } 
    } 
}

Можно ли запустить этот код на двух компьютерах в одной сети? Я пробовал, но похоже, что это работает только на том же компьютере. Есть ли проблема с сетью или код просто не может передать go на разные компьютеры в сети? Кстати, это не мой код, я взял его из inte rnet в учебных целях. Заранее большое спасибо.

1 Ответ

0 голосов
/ 14 июля 2020

Да, определенно возможно установить sh сокетное соединение между двумя компьютерами в ОДНОЙ сети. В любом случае мне проще сделать это с java. net .Socket , мой пример здесь: (Это наследуемый класс)

/**
 *
 * @param ipAddress See {@link Client#ipAddress}
 * @param port See {@link Client#port}
 * @param prints See {@link Client#prints}
 * @param printNewline See {@link Client#printNewline}
 * @param printColor See {@link Client#printColor}
 * @param printViaLogger See {@link Client#printViaLogger}
 * @param logger See {@link Client#logger}
 */
public Client(String ipAddress, String port,boolean prints, boolean printNewline, CConsoleColor printColor, boolean printViaLogger,LatestLogger logger) {

    this.ipAddress = ipAddress;
    this.port = port;
    this.prints = prints;
    this.printNewline = printNewline;
    this.printColor = printColor;

    this.printViaLogger = printViaLogger;
    this.logger = logger;

}

/**
 *  This method starts the client
 */
public void connect() {
    try {

        socket = new Socket();
        InetSocketAddress address = new InetSocketAddress(ipAddress,Integer.parseInt(port));
        socket.connect(address,5000);
        print("Client connected (" + ipAddress + ":" + port + ")");

        listening = true;

        scanner = new Scanner(new BufferedReader(new InputStreamReader(socket.getInputStream())));

        writer = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));

        connected = true;

        startListening();

    } catch (IOException e) {
        connected = false;
    }
}

/**
 *
 * @param args String[] has to contain all arguments you want so sent
 */
public void sendPacket(String[] args) {

    String sending = "";

    /* Getting all args */
    for (int i = 0; i < args.length; i++) {

        /* Writing current args into the OutputStream */
        sending = sending + args[i] + " ";

    }

    writer.println(sending);
    writer.flush();

    print("Client (" + socket.getInetAddress() + ") sending new Packet");

}

/**
 *  This method gets called when the server is started, because this method contains the scanner for the socket-connection
 */
private void startListening() {
    new Thread(new Runnable() {
        @Override
        public void run() {

            String incoming;

            while (listening) {

                if(scanner.hasNextLine() && (incoming = scanner.nextLine()) != null) {

                    /* Run 'handle' method */
                    handle(incoming);

                    print("Client (" + socket.getInetAddress() + ") received a new Packet");

                }

            }

        }
    }).start();
}

/**
 *
 * @param incoming String is the incoming string from the server
 */
public void handle(String incoming) {

    /* Empty method to change */

}

И здесь это мой класс сервера:

/**
 *
 * @param socket See {@link Server#socket}
 * @param scanner See {@link Server#scanner}
 * @param writer See {@link Server#writer}
 * @param prints See {@link Server#prints}
 * @param printNewline See {@link Server#printNewline}
 * @param printColor See {@link Server#printColor}
 * @param printViaLogger See {@link Server#printViaLogger}
 * @param logger See {@link Server#logger}
 */
public Server(Socket socket, Scanner scanner, PrintWriter writer, boolean prints, boolean printNewline, CConsoleColor printColor,ServerManager manager, boolean printViaLogger, LatestLogger logger) {

    /* Defining variables */
    this.socket = socket;
    this.scanner = scanner;
    this.writer = writer;
    this.prints = prints;
    this.printNewline = printNewline;
    this.printColor = printColor;
    this.manager = manager;

    this.printViaLogger = printViaLogger;
    this.logger = logger;

}

/**
 *  This is the run method of your Serverthread
 */
@Override
public void run() {

    /* Create 'incoming' String */
    String incoming = null;

    while (true) {

        /* Searching for next line */
        if (scanner.hasNextLine() && (incoming = scanner.nextLine()) != null) {

            print("Server (" + socket.getInetAddress() + ") received a new Packet");

            /* Run 'handle' method */
            manager.handle(incoming,this);

        }

    }

}

/**
 *
 * @return {@link Server#socket}
 */
public Socket getSocket() {
    return socket;
}

/**
 *
 * @param args String[] has to contain all arguments of the packet you want to send
 */
public void sendPacket(String[] args) {

    String sending = "";

    /* Getting all args */
    for (int i = 0; i < args.length; i++) {

        /* Writing current args into the OutputStream */
        sending = sending + args[i] + " ";

    }

    writer.println(sending);
    writer.flush();

    print("Server (" + socket.getInetAddress() + ") sending new Packet");

}

А вот мой класс ServerManager:

/**
 *
 * @param ipAddress See {@link ServerManager#ipAddress}
 * @param port See {@link ServerManager#port}
 * @param prints See {@link ServerManager#prints}
 * @param printNewline See {@link ServerManager#printNewline}
 * @param printColor See {@link ServerManager#printColor}
 * @param maxConnection See {@link ServerManager#maxConnection}
 * @param printViaLogger See {@link ServerManager#printViaLogger}
 * @param logger See {@link ServerManager#logger}
 */
public ServerManager(String ipAddress,String port,boolean prints, boolean printNewline, CConsoleColor printColor, int maxConnection, boolean printViaLogger, LatestLogger logger) {

    /* Defining variables */
    this.ipAddress = ipAddress;
    this.port = port;
    this.maxConnection = maxConnection;
    this.prints = prints;
    this.printNewline = printNewline;
    this.printColor = printColor;

    this.printViaLogger = printViaLogger;
    this.logger = logger;

}

/**
 * If your want to start the server you have to run this method
 */
public void connect() {

    /* Creating new Thread */
    new Thread(new Runnable() {
        @Override
        public void run() {
            try {

                /* Create variables */
                Socket remoteClientSocket;
                Scanner scanner;
                PrintWriter writer;

                print("Server starting...");

                /* Creating and Defining ServerSocket variable */
                ServerSocket serverSocket = new ServerSocket(Integer.valueOf(port));

                print("Waiting for conenctions...");

                /* Start listening */
                while (true) {

                    /* Checking limit */
                    if(connectedClients.size() <= maxConnection) {

                        /* Limit not fulfill */

                        /* Defining 'remoteClientSocket' variables */
                        remoteClientSocket = serverSocket.accept();

                        print("Client connected: " + remoteClientSocket.getRemoteSocketAddress());

                        /* Defining 'scanner' variables */
                        scanner = new Scanner(new BufferedReader(new InputStreamReader(remoteClientSocket.getInputStream())));

                        /* Defining 'writer' variables */
                        writer = new PrintWriter(new OutputStreamWriter(remoteClientSocket.getOutputStream()));

                        server = new Server(remoteClientSocket,scanner,writer,prints,printNewline,printColor,getInstance(),printViaLogger,logger);

                        /* Starting server */
                        server.start();

                        /* Adding server to list */
                        connectedClients.add(server);

                        /* Add 1 to maxConnection */
                        maxConnection++;

                    }else {

                        print("Limit reached");

                        break;

                    }
                }

            }catch (Exception e) {

                StringWriter sw = new StringWriter();

                PrintWriter pw = new PrintWriter(sw);

                e.printStackTrace(pw);

                String exeptionAsString = sw.toString();

                print(exeptionAsString);

            }
        }
    }).start();

}

/**
 *
 * @param incoming String has to be the incoming string from the client
 * @param server Server has to be the server from which the packet was received
 */
public void handle(String incoming, Server server) {

    // Empty method for handle

}

/**
 * If you want to disconnect an client from the server you have to run this method
 * @param server The client you want to disconnect
 */
public void disconnectClient(Server server) {
    try {

        server.getSocket().close();

        connectedClients.remove(server);

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

}

почти все установленные переменные были объявлены, но без значений, надеюсь, это помогло вам

...