2015-05-27 1 views
2

Это мой первый раз, когда мы встречаемся с Sockets, и он работал до сих пор. В принципе, у меня есть пользовательский класс ServerSocket с именем Server и пользовательский класс Socket с именем Client.Пользовательский класс Java Socket

Когда клиент пытается подключиться к серверу, сервер выполняет небольшую проверку, чтобы убедиться, что на самом деле клиент пытается установить соединение, а не какой-либо другой сокет, потому что у Клиента есть определенные методы, которые мне нужны.

Однако эта проверка всегда возвращает значение false. Вот мой сервер код подключения:

package me.eli.server; 

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.io.PrintStream; 
import java.io.PrintWriter; 
import java.net.ServerSocket; 
import java.net.Socket; 
import java.util.HashMap; 
import java.util.Map; 

import me.eli.client.Client; 

public class Server extends ServerSocket { 

private final Map<Client, IOPair> clients = new HashMap<Client, IOPair>(); 

public Server(final int port) throws IOException { 
    super(port); 
    System.out.println("Server started on " + getLocalPort() + "... Waiting for client!"); 
} 

public Client waitOnClient() throws IOException { 
    final Socket generalClient = accept(); 
    final Client client; 
    if(!(generalClient instanceof Client)) { 
     client = null; 
     PrintWriter out = new PrintWriter(generalClient.getOutputStream(), true); 
     out.println("Access denied: " + generalClient.getClass().getSimpleName()); 
     log("Invalid client: " + generalClient.getClass().getName() + " (" + generalClient.getInetAddress().getHostAddress() + ")"); 
     out.close(); 
    } else 
     client = (Client) generalClient; 
    if(client == null) 
     return null; 
    client.setServer(this); 
    BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream())); 
    PrintWriter out = new PrintWriter(client.getOutputStream(), true); 
    broadcast(client.getName() + " has joined."); 
    clients.put(client, new IOPair(in, out)); 
    System.out.println("Client (" + client.getName() + ") connected from " + client.getInetAddress().getHostAddress()); 
    out.println("Connected! Welcome to the server."); 
    return client; 
} 

@Override 
public void close() throws IOException { 
    for(Client c : getClients()) 
     kick(c, "Server closed"); 
    super.close(); 
} 

public void kick(Client c, String reason) { 
    try { 
     c.message("disconnect", reason); 
     c.close(); 
    } catch(IOException e) { 
     log("Failed to kick " + c.getName() + ": " + e.getMessage()); 
     c.message("error", "Failed to disconnect"); 
    } 
} 

public void log(String message) { 
    getServerOut().println(message); 
} 

public void log(String source, String message) { 
    log("<" + source + "> " + message); 
} 

public void broadcast(String message) { 
    log("broadcast", message); 
    for(Client c : getClients()) 
     c.message("broadcast", message); 
} 

public Client[] getClients() { 
    return clients.keySet().toArray(new Client[clients.keySet().size()]); 
} 

public BufferedReader getClientIn(Client c) { 
    return clients.get(c).getIn(); 
} 

public PrintWriter getClientOut(Client c) { 
    return clients.get(c).getOut(); 
} 


public InputStream getServerIn() { 
    return System.in; 
} 

public PrintStream getServerOut() { 
    return System.out; 
} 

public static boolean isServerRunningOn(final int port) { 
    try { 
     new ServerSocket(port).close(); 
     return false; 
    } catch(IOException e) { 
     return true; 
    } 
} 

} 

А вот мой клиент код подключения:

package me.eli.client; 

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.io.PrintStream; 
import java.io.PrintWriter; 
import java.net.Socket; 

import me.eli.server.IOPair; 
import me.eli.server.Server; 

public class Client extends Socket { 

private Server server; 
private final IOPair serverio; 
private final String name; 

public Client(final String host, final int port) throws IOException { 
    this(host, port, "Guest-" + (int) (Math.random() * 10000)); 
} 

public Client(final String host, final int port, final String name) throws IOException { 
    super(host, port); 
    System.out.println("Connected to server on " + host + ":" + port); 
    BufferedReader in = new BufferedReader(new InputStreamReader(getInputStream())); 
    PrintWriter out = new PrintWriter(getOutputStream(), true); 
    this.name = name; 
    this.serverio = new IOPair(in, out); 
    String input; 
    if((input = in.readLine()) != null) 
     System.out.println("<Welcome message> " + input); 
    out.println("Yay! I'm connected!"); 
} 

@Override 
public synchronized void close() throws IOException { 
    if(serverio != null) { 
     if(server != null) 
      server.broadcast(getName() + " has disconnected."); 
     message("server", "Disconnected."); 
     super.close(); 
     serverio.getIn().close(); 
     serverio.getOut().close(); 
    } else 
     super.close(); 
} 

public void message(String source, String message) { 
    getClientOut().println("<" + source + "> " + message); 
} 

public String getName() { 
    return name; 
} 

public void setServer(Server server) { 
    this.server = server; 
} 

public Server getServer() { 
    return server; 
} 

public BufferedReader getServerIn() { 
    return serverio.getIn(); 
} 

public PrintWriter getServerOut() { 
    return serverio.getOut(); 
} 

public InputStream getClientIn() { 
    return System.in; 
} 

public PrintStream getClientOut() { 
    return System.out; 
} 

} 

Я не самый опытный с сетью, но это меня смущает, потому что я действительно соединиться с моим Класс клиента. Заранее спасибо!

+0

Метод waitOnClient вызывается внутри Server, настраиваемого класса ServerSocket. – DonkeyCore

+0

@ DonkeyTeeth2013- Было бы лучше, если бы вы добавили коды для обоих классов! Было бы трудно сказать, основываясь только на этом большом доказательстве. –

ответ

2

Сервер выполняет небольшую проверку, чтобы убедиться, что это на самом деле клиент, что он пытается сделать это подключение

невозможно и бессмысленно. Класс Client находится на другом конце соединения. Он не магически передается вашему методу accept(). Если вы хотите проверить свой клиент, вам придется что-то встраивать в свой протокол приложений.

Примечания:

  • Вызывающие Client.setServer() это так же бесполезно. Это не магически передается клиенту.
  • Можно получить свой класс ServerSocket -derived для создания объектов Client вместо Socket объектов в своем методе accept(), но это фактически не решает проблему, которую вы пытаетесь решить.
+0

Также сообщите ему о rmi, если оператору требуется динамический класс download/lookup. И, + 1, как обычно. :) –

+0

Спасибо! Я посмотрю на Java RMI, но на самом деле мне это удалось, переопределив метод accept(). Я не уверен, хотя это хорошая вещь или не рекомендуется? – DonkeyCore

+0

Это не решит вашу проблему. Переопределение 'accept()' просто означает, что * каждый * принятый сокет является «клиентом», независимо от того, кто подключается к вам. Это не то, чего вы пытаетесь достичь. – EJP