read - use sockets in java
Sockets de Java: ¿múltiples subprocesos de cliente en el mismo puerto en la misma máquina? (6)
Asi que. Empezar:
Puede aceptar más clientes con un solo servidor, porque solo acepta uno en el método de run
. Simplemente tiene que llamar a accept()
por segunda vez.
Luego, en su bucle for: primero debe crear cada vez un nuevo objeto Client
. Luego puede llamar a c[i].start();
y no c.start()
.
¿Ahora puedo tener varias instancias de Cliente en diferentes subprocesos que intentan conectarse en el mismo puerto de la máquina actual?
Sí tu puedes. Simplemente crea nuevos Temas y ejecútalos. Esto debería funcionar perfectamente.
esperar que el servidor lea y escriba datos con aislamiento entre los clientes
Puedes usar tu experiencia de las técnicas básicas de IO como con file-io:
OutputStream os = socket.getOutputStream();
PrintStream pw = new PrintStream(os, true); // Or PrintWriter, I don''t know what the best one is.
pw.println("Hello, other side of the connection!");
Y para leer usa un BufferedReader.
Soy nuevo en la programación de Socket en Java y estaba tratando de entender si el código siguiente no es una acción incorrecta. Mi pregunta es:
¿Puedo tener múltiples clientes en cada hilo tratando de conectarme a una instancia de servidor en el mismo programa y esperar que el servidor lea y escriba datos con aislamiento entre los clientes "
public class Client extends Thread
{
...
void run()
{
Socket socket = new Socket("localhost", 1234);
doIO(socket);
}
}
public class Server extends Thread
{
...
void run()
{
// serverSocket on "localhost", 1234
Socket clientSock = serverSocket.accept();
executor.execute(new ClientWorker(clientSock));
}
}
¿Ahora puedo tener varias instancias de Cliente en diferentes subprocesos que intentan conectarse en el mismo puerto de la máquina actual?
Por ejemplo,
Server s = new Server("localhost", 1234);
s.start();
Client[] c = new Client[10];
for (int i = 0; i < c.length; ++i)
{
c.start();
}
En este ejemplo, su Server
acepta y maneja una conexión de cliente a la vez. Puede tener tantos Client
como desee intentando conectarse, pero solo se manejarán uno a la vez.
No es evidente si su lógica de ejecutor es multiproceso, ya que no proporcionó la implementación. Si el ejecutor delega en un subproceso de subprocesos o algo así, deberá asegurarse de que su ClientWorker
es seguro para subprocesos, ya que tendrá varias instancias ejecutándose en paralelo.
Por supuesto, supongo que su Client
está protegido contra subprocesos, ya que su pregunta es solo sobre el Server
.
Sí, no importa si sus clientes son locales o remotos. Lo importante en su ejemplo es que ClientWorker es seguro para subprocesos, ya que su servidor tendrá múltiples instancias de esa clase (una para cada conexión de cliente).
Sí, sin embargo, solo un cliente podrá conectarse por ejecución de subprocesos como está escrito.
Puede poner su servidor run () dentro de un ciclo verdadero while para permitir que se conecten varios clientes. Dependiendo del ejecutor, se ejecutarán en serie o en paralelo.
public class Server extends Thread
{
...
void run()
{
while(true){
// serverSocket on "localhost", 1234
Socket clientSock = serverSocket.accept();
executor.execute(new ClientWorker(clientSock));
}
}
}
Siempre que solo tenga un objeto que intente vincular el puerto para escuchar, no hay problema con la conexión de múltiples clientes.
Puedes probar algo en estas líneas
public class MultiThreadServer extends Application {
// Text area for displaying contents
private TextArea ta = new TextArea();
// Number a client
private int clientNo = 0;
@Override // Override the start method in the Application class
public void start(Stage primaryStage) {
// Create a scene and place it in the stage
Scene scene = new Scene(new ScrollPane(ta), 450, 200);
primaryStage.setTitle("MultiThreadServer"); // Set the stage title
primaryStage.setScene(scene); // Place the scene in the stage
primaryStage.show(); // Display the stage
new Thread( () -> {
try {
// Create a server socket
ServerSocket serverSocket = new ServerSocket(8000);
ta.appendText("MultiThreadServer started at "
+ new Date() + ''/n'');
while (true) {
// Listen for a new connection request
Socket socket = serverSocket.accept();
// Increment clientNo
clientNo++;
Platform.runLater( () -> {
// Display the client number
ta.appendText("Starting thread for client " + clientNo +
" at " + new Date() + ''/n'');
// Find the client''s host name, and IP address
InetAddress inetAddress = socket.getInetAddress();
ta.appendText("Client " + clientNo + "''s host name is "
+ inetAddress.getHostName() + "/n");
ta.appendText("Client " + clientNo + "''s IP Address is "
+ inetAddress.getHostAddress() + "/n");
});
// Create and start a new thread for the connection
new Thread(new HandleAClient(socket)).start();
}
}
catch(IOException ex) {
System.err.println(ex);
}
}).start();
}
// Define the thread class for handling new connection
class HandleAClient implements Runnable {
private Socket socket; // A connected socket
/** Construct a thread */
public HandleAClient(Socket socket) {
this.socket = socket;
}
/** Run a thread */
public void run() {
try {
// Create data input and output streams
DataInputStream inputFromClient = new DataInputStream(
socket.getInputStream());
DataOutputStream outputToClient = new DataOutputStream(
socket.getOutputStream());
// Continuously serve the client
while (true) {
// Receive radius from the client
double radius = inputFromClient.readDouble();
// Compute area
double area = radius * radius * Math.PI;
// Send area back to the client
outputToClient.writeDouble(area);
Platform.runLater(() -> {
ta.appendText("radius received from client: " +
radius + ''/n'');
ta.appendText("Area found: " + area + ''/n'');
});
}
}
catch(IOException e) {
ex.printStackTrace();
}
}
}
/**
* The main method is only needed for the IDE with limited
* JavaFX support. Not needed for running from the command line.
*/
public static void main(String[] args) {
launch(args);
}
}