我现在正在使用Socket和ServerSocket对象处理Java中的客户端 - 服务器通信。 一旦服务器初始化,它就会通过来自ServerSocket类的accept()方法与新客户端保持一致;我立即提供将此套接字放在服务器上的客户端映射中: - keys:ClientNode(Socket s,CommunicationChannels channels); - values:Info(); (CommunicationChannels包含来自socket的ObjectOutputStream和ObjectInputStream; Info包含有关客户端的一些信息,如用户名,消息等。)。
鉴于此,在开头,套接字除了套接字本身之外在客户端上没有任何其他信息,首先在地图上插入是map.put(ClientNode,null)。之后我将填写“价值”字段。
现在,在Client类中,我将初始化一个Socket(“127.0.0.1”,13001),即带有环回地址和门13001.一旦初始化了通信通道,客户端就连接到服务器。
客户端启动后,他通过RMI(存根)库获取服务器的远程副本,服务器使register()方法可用:它允许使用此方法(从客户端)写入请求的信息地图。
客户端如何返回已在服务器上注册的套接字?坦率地说,我认为来自ServerSocket的accept()方法可以将在启动客户端上建立的套接字带回服务器,即使用新的Socket(“127.0.0.1”,13001),但在我看来,这不是发生。
在这里你可以找到部分代码,这样你就可以更好地理解我在说什么。我已经考虑了一些我需要与你分享的东西。
public class Server implements Runnable, RemoteServices {
...
private Map<ClientNode, Info> map = new HashMap<ClientNode, Info>();
...
public void run() {
ServerSocket ss = null;
try {
ss = new ServerSocket();
while (true) {
if (!ss.isBound()) {
ss.bind(new InetSocketAddress(ipServer, port));
}
Socket client = ss.accept();
CommunicationChannels channels = new CommunicationChannels(new ObjectOutputStream(client.getOutputStream()), new ObjectInputStream(client.getInputStream()));
map.put(new ClientNode(client, channels), null);
}
} catch (IOException e) {
e.printStackTrace();
}
}
// RemoteServices implementa Remote e mette a disposizione register()
public void register(Info info) throws RemoteException {
// TODO
}
public class Client implements Runnable {
...
...
@Override
public void run() {
Socket client = null;
try {
client = new Socket(ipServer, port);
out = new ObjectOutputStream(client.getOutputStream());
in = new ObjectInputStream(client.getInputStream());
Registry registry = LocateRegistry.getRegistry("127.0.0.1");
stub = (RemoteServices) registry.lookup("remoteObject");
Info info = new Info();
info.setID(getID());
info.setUsername("Giordano");
stub.register(info);
} catch (IOException e) {
System.err.println("Spiacente: il server ha terminato l'esecuzione.");
e.printStackTrace();
} catch (NotBoundException e) {
e.printStackTrace();
}
}
}
说明:
最后,main()方法:
public static void main(String[] args) {
Server server = new Server("127.0.0.1", 13001);
RemoteServices stub;
try {
stub = (RemoteServices) UnicastRemoteObject.exportObject(server, 0);
Registry registry = LocateRegistry.getRegistry();
registry.bind("remoteObject", stub);
(new Thread(server)).start();
} catch (RemoteException e) {
System.err.println("Verificare l'apertura dei registri");
} catch (AlreadyBoundException e) {
System.err.println("Server già attivo. Controllare che i registri siano chiusi correttamente.");
}
}
public static void main(String[] args) { Client client = new Client("127.0.0.1", 13001);
new Thread(client).start();
}
我真的希望一切都清楚,你可以帮助我。