2016-01-24 174 views
0

我正在嘗試編寫一個客戶端服務器程序來處理多個客戶端請求使用服務器(Server1),而服務器又從另一個服務器(計算服務器)請求計算。多個客戶端和多個服務器使用線程

客戶端要求形式爲a1b1 + a2b2 + ...的表達式,其中a1,b1等是2X2矩陣。用戶然後輸入表達式,然後輸入2X2矩陣的值。客戶將每個值與','連接起來,同時將每個矩陣附加';'並將結果字符串發送到服務器(Server1)。

服務器(Server1)在接收到該表達式後,將其分解爲標記(用'+'分隔)並將令牌(a1和b1的值)轉發給另一個計算服務器。計算服務器(1)從服務器1接收令牌,(2)提取2×2矩陣並執行它們的矩陣乘法,以及(3)將矩陣乘法的結果返回給服務器1。 Server1然後計算計算服務器返回的值的總和,並將最終結果發送回客戶端。

例如,如果用戶輸入像'a1b1 + a2b2'(無空格)的表達式,並且值1,1,1,1(對於矩陣a1)等,則客戶端向表單1中的字符串發送一個字符串'1,1,1,1; 2,2,2,2; + 3,3,3,3; 4,4,4,4; +'。 Server1發送1,1,1,1; 2,2,2,2;到計算服務器。計算服務器計算{1,1,1,1}和{2,2,2,2}的矩陣乘法,並將結果{4,4,4,4}返回給Server1。 Server1再次發送3,3,3,3; 4,4,4,4;到計算服務器等等。最後,Server1將表達式{28,28,28,28}的結果返回給客戶端。

我的代碼如下:

TCPClient.java

import java.io.*; 
import java.net.*; 

public class TCPClient{ 
public static void main(String [] args) throws Exception{ 
    Socket s = new Socket("127.0.0.1",5555); 
    DataOutputStream out = new DataOutputStream(s.getOutputStream()); 

    System.out.print("Enter an expression of the form a1b1+a2b2... : "); 
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 
    String exp = br.readLine(); 
    String exp2 = ""; 
    int terms = exp.length() - exp.replace("+", "").length() + 1; 
    int i = 1; 
    String input; 
    do{ 
     System.out.print("\nEnter value for element 00 of a" + i + ": "); 
     input = br.readLine(); 
     exp2 += input + ","; 
     System.out.print("Enter value for element 01 of a" + i + ": "); 
     input = br.readLine(); 
     exp2 += input + ","; 
     System.out.print("Enter value for element 10 of a" + i + ": "); 
     input = br.readLine(); 
     exp2 += input + ","; 
     System.out.print("Enter value for element 11 of a" + i + ": "); 
     input = br.readLine(); 
     exp2 += input + ";"; 

     System.out.print("\nEnter value for element 00 of b" + i + ": "); 
     input = br.readLine(); 
     exp2 += input + ","; 
     System.out.print("Enter value for element 01 of b" + i + ": "); 
     input = br.readLine(); 
     exp2 += input + ","; 
     System.out.print("Enter value for element 10 of b" + i + ": "); 
     input = br.readLine(); 
     exp2 += input + ","; 
     System.out.print("Enter value for element 11 of b" + i + ": "); 
     input = br.readLine(); 
     exp2 += input + ";+"; 

     i++; 
    }while(i <= terms); 

    System.out.println("\nExpression sent to server = "+exp2);  
    out.writeUTF(exp2); 

    DataInputStream in = new DataInputStream(s.getInputStream()); 
    String result = in.readUTF(); 
    System.out.println("\nResult of expression is "+ result); 
    s.close(); 
} 
} 

TCPServer1.java

import java.io.*; 
import java.net.*; 

public class TCPServer1{ 
public static void main(String [] args) throws Exception{ 
    ServerSocket ss = new ServerSocket(5555); 
    System.out.println("Server started..."); 

    while(true){ 
     Socket s = ss.accept(); 
     Connection c = new Connection(s); 
    } 
} 
} 

class Connection extends Thread{ 
Socket c; 
DataInputStream in; 
DataOutputStream out; 
public Connection(Socket c) throws Exception{ 
    this.c = c; 
    in = new DataInputStream(c.getInputStream()); 
    out = new DataOutputStream(c.getOutputStream()); 
    this.start(); 
} 
public void run(){ 
    try{ 
     String data = new String(); 
     data = in.readUTF(); 
     System.out.println("Received from client: " + data); 
     data = data.substring(0, data.length()-1); 
     System.out.println("data: " + data); 
     String[] tokens = data.split("\\+"); 
     System.out.println("tokens[0]: " + tokens[0]); 
     int[][] finalsum = new int [2][2]; 

     Socket s = new Socket("127.0.0.1",6666); 
     DataOutputStream out2 = new DataOutputStream(s.getOutputStream()); 

     int numtokens = tokens.length; 
     int i = 0; 
     while (i < numtokens) { 
      System.out.println("Writing to CM: " + tokens[i]); 
      out2.writeUTF(tokens[i]); 
      DataInputStream in2 = new DataInputStream(s.getInputStream()); 
      String matmul = in2.readUTF(); 
      System.out.println("Received from Computation Machine: " + matmul); 
      findSum(finalsum, matmul); 
      System.out.println("Finalsum intermediate: " + finalsum[0][0] + " " + finalsum[0][1] + " " + finalsum[1][0] + " " + finalsum[1][1]); 
      i++; 
     } 
     String finalres = String.valueOf(finalsum[0][0]) + "," +String.valueOf(finalsum[0][1]) + ","; 
     finalres += String.valueOf(finalsum[1][0]) + "," + String.valueOf(finalsum[1][1]); 
     System.out.print("finalres to be sent to client: " + finalres); 
     out.writeUTF(finalres); 
    }catch(Exception e){ 
     e.printStackTrace(); 
    }finally{ 
     try{ 
      c.close(); 
     }catch(Exception e){ 
      e.printStackTrace(); 
     } 
    } 
} 

public static void findSum(int [][] finalsum, String matmul) { 
    int [][] arr = new int [2][2]; 
    String[] tokens = matmul.split(","); 

    arr[0][0] = Integer.parseInt(tokens[0]); 
    arr[0][1] = Integer.parseInt(tokens[1]); 
    arr[1][0] = Integer.parseInt(tokens[2]); 
    arr[1][1] = Integer.parseInt(tokens[3]); 

    for(int i = 0; i < 2; i++) 
     for(int j = 0; j < 2; j++) 
      finalsum[i][j] += arr[i][j]; 
} 
} 

ComputationServer.java

import java.io.*; 
import java.net.*; 

public class ComputationServer { 
public static void main(String [] args) throws Exception{ 
    ServerSocket ss = new ServerSocket(6666); 
    System.out.println("Computation Server started..."); 
    int count = 1; 

    Socket s = ss.accept(); 
    DataInputStream in; 
    DataOutputStream out; 
    in = new DataInputStream(s.getInputStream()); 
    out = new DataOutputStream(s.getOutputStream()); 

    while(true){ 
     System.out.println("Entered CM " + (count++) + " times"); 
     String data = in.readUTF(); 
     System.out.println("Received from server: " + data); 

     String[] tokens = data.split(";"); 
     System.out.println("tokens[0]: " + tokens[0]); 
     System.out.println("tokens[1]: " + tokens[1]); 

     String[] subtoken1 = tokens[0].split(","); 
     String[] subtoken2 = tokens[1].split(","); 
     int[][] first = new int [2][2]; 
     int[][] second = new int [2][2]; 

     first[0][0] = Integer.parseInt(subtoken1[0]); 
     first[0][1] = Integer.parseInt(subtoken1[1]); 
     first[1][0] = Integer.parseInt(subtoken1[2]); 
     first[1][1] = Integer.parseInt(subtoken1[3]); 

     second[0][0] = Integer.parseInt(subtoken2[0]); 
     second[0][1] = Integer.parseInt(subtoken2[1]); 
     second[1][0] = Integer.parseInt(subtoken2[2]); 
     second[1][1] = Integer.parseInt(subtoken2[3]); 

     int[][] res = new int [2][2]; 

     for(int i = 0; i < 2; i++) 
      for(int j = 0; j < 2; j++) 
       for(int k = 0; k < 2; k++) 
        res[i][j] += first[i][k] * second[k][j]; 

     String matmul = String.valueOf(res[0][0]) + "," +String.valueOf(res[0][1]) + ","; 
     matmul += String.valueOf(res[1][0]) + "," + String.valueOf(res[1][1]); 
     System.out.println("matmul: " + matmul); 
     out.writeUTF(matmul); 
     //out.flush(); 
    } 
} 
} 

爲了執行,我先啓動Computation服務器,然後啓動Server1,然後啓動客戶端程序。

我面臨的問題是我的程序對第一個客戶端正常工作,但如果我嘗試爲第二個客戶端計算此值,計算服務器不接受進一步的請求。

如果我按照以下方式更改我的計算服務器,則它不接受來自Server1的第二個令牌(對於第一個客戶端)。

ComputationServer.java

import java.io.*; 
import java.net.*; 

public class ComputationServer { 
public static void main(String [] args) throws Exception{ 
    ServerSocket ss = new ServerSocket(6666); 
    System.out.println("Computation Server started..."); 
    int count = 1; 

    while(true){ 
     System.out.println("Entered CM " + (count++) + " times"); 
     Socket s = ss.accept(); 
     DataInputStream in; 
     DataOutputStream out; 
     in = new DataInputStream(s.getInputStream()); 
     out = new DataOutputStream(s.getOutputStream()); 
     String data = in.readUTF(); 
     System.out.println("Received from server: " + data); 
//rest of the code same as above 

任何幫助將非常感激。提前致謝!

+1

哦,男人,你的問題與你的數據輸入和輸出無關,那麼你爲什麼打擾我們這些細節呢?更好地描述你的意思是「它行不通」。 – Heri

+1

請不要介意,這是我在這裏的第一篇文章。 –

回答

1

我認爲「它不起作用」意味着來自第二個客戶端的呼叫永遠不會到達您的ComputationServer。您的ComputationServer只接受一個連接,然後無限循環,永遠不會再輸入accept方法。那麼,爲什麼你會期望你的server1在收到第二個請求後可以打開一個新的連接?

+0

你說得對,計算服務器不接受第二個請求。但我也嘗試將接受部分放在循環中,如下所示: 'while(true){s} ss.accept(); DataInputStream in; DataOutputStream輸出; in = new DataInputStream(s.getInputStream()); out = new DataOutputStream(s.getOutputStream()); ' 在這種情況下,計算服務器不處理來自Server1的第二個令牌。你能否提出一個解決方案? –