PDA

View Full Version : Client - Server MultiThreading


Gimmy2
17-05-2011, 08:37
Ciao a tutti! Premetto che sono nuovo riguardo la programmazione java e ad oggetti. Ho la seguente situazione: ho un server che quando viene contattato dal client genera un thread e una socket e scambia dati con il client. Fin qui tutto ok, pero ora vorrei che quando il client contatta il server, quest'ultimo generi 3 o piu thread ognuno dei quali calcola dei dati e li passa, sempre sulla stessa socket in modo concorrente al client.

Server.java

import java.util.*;
import java.lang.*;
import java.io.*;
import java.net.*;

/**
* This is to help people to write Client server application
* I tried to make it as simple as possible... the client connect to the server
* the client send a String to the server the server returns it in UPPERCASE thats all
*/
public class Server {

// the socket used by the server
private ServerSocket serverSocket;
public int i=0;
// server constructor
Server(int port) {

/* create socket server and wait for connection requests */
try
{
serverSocket = new ServerSocket(port);
System.out.println("Server waiting for client on port " + serverSocket.getLocalPort());

while(true)
{
Socket socket = serverSocket.accept(); // accept connection
System.out.println("New client asked for a connection");
for(i=0; i<3; i++){
TcpThread t = new TcpThread(socket); // make a thread of it
// TcpThread t2 = new TcpThread(socket); // make a thread of it
// TcpThread t3 = new TcpThread(socket); // make a thread of it
System.out.println("Starting thread " + i);
t.start();
// t2.start();
// t3.start();
}

}
}
catch (IOException e) {
System.out.println("Exception on new ServerSocket: " + e);
}
}

// you must "run" server to have the server run as a console application
public static void main(String[] arg) {
// start server on port 1500
new Server(1500);
}

/** One instance of this thread will run for each client */
class TcpThread extends Thread {
// the socket where to listen/talk
Socket socket;
DataInputStream Sinput;
DataOutputStream Soutput;

TcpThread(Socket socket) {
this.socket = socket;
}
synchronized public void run() {
/* Creating both Data Stream */
System.out.println("Thread " + i + " trying to create Object Input/Output Streams");
try
{
// create output first
Soutput = new DataOutputStream(socket.getOutputStream());
// Soutput.flush();
Sinput = new DataInputStream(socket.getInputStream());
}
catch (IOException e) {
System.out.println("Exception creating new Input/output Streams: " + e);
return;
}
System.out.println("Thread " + i + " waiting for a String from the Client");
// read a String (which is an object)
try {

// creazione vettore di interi
double[] vettore = new double[10];
for(int i=0; i<10; i++){
vettore[i] = Math.random()*Integer.MAX_VALUE;
}
// individuazione del valore var1
double var1=0;
for(int i=0; i<10; i++){
if(i==0)
var1=vettore[i];
if(var1>vettore[i])
var1=vettore[i];
}
// mi faccio inviare il var2 dal professor
double var2 = (double) Sinput.readDouble();
// var1 = var1.toUpperCase();
System.out.println("Ricevuto var2 = " + var2);
// se il mio var1 è > del suo var2 allora glielo invio
if(var1>var2){
System.out.println("var1 = " + var1 + " > var2 = " + var2 + " => INVIO\n\n");
Soutput.writeDouble(var1);
// Soutput.flush();
}else{
System.out.println("var1 = " + var1 + " < var2 = " + var2 + " => NON INVIO\n\n");
}
}
catch (IOException e) {
System.out.println("Exception reading/writing Streams: " + e);
return;
}
// will surely not happen with a String
// catch (ClassNotFoundException o) {
// }
finally {
try {
Soutput.close();
Sinput.close();
}
catch (Exception e) {
}
}
}
}

}


Client.java

import java.util.*;
import java.lang.*;
import java.io.*;
import java.net.*;

public class Client {

public static double var2=0;

DataInputStream Sinput; // to read the socker
DataOutputStream Soutput; // to write on the socket
Socket socket;

// Constructor connection receiving a socket number
Client(int port) {
// we use "localhost" as host name, the server is on the same machine
// but you can put the "real" server name or IP address
try {
socket = new Socket("localhost", port);
}
catch(Exception e) {
System.out.println("Error connectiong to server:" + e);
return;
}
System.out.println("Connection accepted " + socket.getInetAddress() + ":" + socket.getPort());

/* Creating both Data Stream */
try
{
Sinput = new DataInputStream(socket.getInputStream());
Soutput = new DataOutputStream(socket.getOutputStream());
}
catch (IOException e) {
System.out.println("Exception creating new Input/output Streams: " + e);
return;
}
// now that I have my connection
// String test = "aBcDeFgHiJkLmNoPqRsTuVwXyZ";



// send the string to the server
System.out.println("Client sending \"" + var2 + "\" to server");
try {
Soutput.writeDouble(var2);
// Soutput.flush();
}
catch(IOException e) {
System.out.println("Error writing to the socket: " + e);
return;
}
// read back the answer from the server
double response;
try {
response = (double) Sinput.readDouble();
System.out.println("Read back from server: " + response);
var2=response;
}
catch(Exception e) {
System.out.println("Problem reading back from server: " + e);
}

try{
Sinput.close();
Soutput.close();
}
catch(Exception e) {}
}

public static void main(String[] arg) throws IOException {

BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String sceltaString;
int scelta=0;
do{
System.out.println("\nCosa vuoi fare?");
System.out.println("1) Contattare i Telescopi. ( var2 attuale = " + var2 + " )");
System.out.println("2) Terminare l'esperimento.");
System.out.print("Scelta: ");

System.out.flush();
sceltaString = in.readLine();

scelta = Integer.parseInt(sceltaString);


switch (scelta){
case 1:
new Client(1500);
break;

case 2:
System.exit(0);

default:
System.out.println("\n!! Scegli il numero 1 o il numero 2 !! \n");
}

}while(scelta!=2);
}
}


Grazi a chiunque possa aiutarmi! :)

Gimmy2
17-05-2011, 18:28
Scusate il doppio post, ma sono incappato in un nuovo problema: in questo codice (che il server postato in precedenza modificato) dichiaro "public synchronized void run() { ... }", quindi teoricamente in quella parte di codice dovrebbe entre un thread alla volta finchè non esce giusto? Invece nell'esecuzione vedo che gli n thread che faccio partire entrano quando vogliono loro in run(), come se synchronized non ci fosse... come mai??

import java.util.*;
import java.lang.*;
import java.io.*;
import java.net.*;

/**
* This is to help people to write Client server application
* I tried to make it as simple as possible... the client connect to the server
* the client send a String to the server the server returns it in UPPERCASE thats all
*/
public class Server {

public static int i=1;
public static double[][] vettore = new double[i][10];
public static double[] var1 = new double[i];
public static int numt = 0;

// the socket used by the server
private ServerSocket serverSocket;
public int j=0;
// server constructor
Server(int port){

/* create socket server and wait for connection requests */
try
{
serverSocket = new ServerSocket(port);
System.out.println("Server waiting for client on port " + serverSocket.getLocalPort());

while(true)
{
Socket socket = serverSocket.accept(); // accept connection
System.out.println("New client asked for a connection");
for(j=0; j<i; j++){
TcpThread t = new TcpThread(socket, j); // make a thread of it
// System.out.println("Starting thread 1");
// TcpThread t2 = new TcpThread(socket, 2); // make a thread of it
// System.out.println("Starting thread 2");
// TcpThread t3 = new TcpThread(socket, 3); // make a thread of it
// System.out.println("Starting thread 3");
System.out.println("Starting thread " + j);
t.start();
// t2.start();
// t3.start();
}

}
}
catch (IOException e) {
System.out.println("Exception on new ServerSocket: " + e);
}
}

// you must "run" server to have the server run as a console application
public static void main(String[] arg) {
// start server on port 1500
new Server(1500);
}

/** One instance of this thread will run for each client */
class TcpThread extends Thread {
// the socket where to listen/talk
int n;
Socket socket;
DataInputStream Sinput;
DataOutputStream Soutput;

TcpThread(Socket socket, int n) {
this.socket = socket;
this.n = n;
}
public synchronized void run() {
// synchronized (this){
numt++;
/* Creating both Data Stream */
System.out.println("Thread " + n + " trying to create Object Input/Output Streams");
try
{
// create output first
Soutput = new DataOutputStream(socket.getOutputStream());
// Soutput.flush();
Sinput = new DataInputStream(socket.getInputStream());
}
catch (IOException e) {
System.out.println("Exception creating new Input/output Streams: " + e);
return;
}
System.out.println("Thread " + n + " waiting for a String from the Client");
// read a String (which is an object)
try {

// creazione vettore di interi
for(int j=0; j<10; j++){
vettore[n][j] = Math.random()*Integer.MAX_VALUE;
}

// individuazione del valore var1[n]
for(int j=0; j<10; j++){
if(j==0)
var1[n]=vettore[n][j];
if(var1[n]>vettore[n][j])
var1[n]=vettore[n][j];
}

// mi faccio inviare il var2 dal professor
double var2 = (double) Sinput.readDouble();
System.out.println("Ricevuto var2 = " + var2);

// se il mio var1 è > del suo var2 allora glielo invio...
if(var1[n]>var2){
double kessvar=1;
System.out.println("Avviso il Professor che gli dto per inviare var1");
Soutput.writeDouble(kessvar);
System.out.println("var1[n] = " + var1[n] + " > var2 = " + var2 + " => INVIO\n\n");
Soutput.writeDouble(var1[n]);
}else{
// ...altrimenti comunico che non invio niente
double kessvar=0;
System.out.println("Avviso il Professor che rimango in attesa");
Soutput.writeDouble(kessvar);
System.out.println("var1[n] = " + var1[n] + " < var2 = " + var2 + " => NON INVIO\n\n");
// Soutput.writeline("NON INVIO UN BEL NIENTE");
}
}
catch (IOException e) {
System.out.println("Exception reading/writing Streams: " + e);
return;
}
// will surely not happen with a String
// catch (ClassNotFoundException o) {
// }
if(numt==i){
try {
Soutput.close();
Sinput.close();
}catch (Exception e) {}

numt=0;
}
// }
}
/* public synchronized void exit(){
int newValue = c - 1;
c = newValue;
try {
Soutput.close();
Sinput.close();
}catch (Exception e) {}
} */

}

/* class funzione {
synchronized void printThis(char c, int times) {
for (int j=0; j<times; j++) {
try{Thread.sleep(1);}
catch(Exception ex) {ex.printStackTrace();}
System.out.print(c);
}
}

} //end class */
}