简体   繁体   English

使用线程的多个客户端和多个服务器

[英]Multiple client and multiple server using threads

I am trying to write a client server program to handle multiple client requests using a server (Server1), which in turn, requests from another server (computation server) for computation. 我正在尝试编写一个客户端服务器程序,以使用服务器(Server1)处理多个客户端请求,该服务器又从另一个服务器(计算服务器)请求进行计算。

The client asks for an expression in the form a1b1+a2b2+... where a1, b1 etc. are 2X2 matrices. 客户端以a1b1 + a2b2 + ...的形式请求表达式,其中a1,b1等是2X2矩阵。 The user then enters the expression, followed by the values of the 2X2 matrices. 然后,用户输入表达式,然后输入2X2矩阵的值。 The client concatenates each value with ',' while appending each matrix with ';' 客户端将每个值与',串联在一起,同时在每个矩阵后附加';'。 and sends the resulting string to the server (Server1) . 并将结果字符串发送到服务器(Server1)。

The server (Server1), on receiving this expression, breaks it down into tokens(separated by '+') and forwards the tokens(values of a1 and b1) to another computation server. 服务器(Server1)在接收到此表达式后,将其分解为令牌(用'+'分隔),并将令牌(a1和b1的值)转发到另一个计算服务器。 The computation server (1)receives the token from Server1, (2) extracts the 2X2 matrices and performs their matrix multiplication and (3) returns the result of matrix multiplication to Server1. 计算服务器(1)从Server1接收令牌,(2)提取2X2矩阵并执行其矩阵乘法,(3)将矩阵乘法的结果返回给Server1。 Server1 then computes the sum of the values returned by the computation server and sends the final result back to the client. 然后,Server1计算由计算服务器返回的值的总和,并将最终结果发送回客户端。

For example if a user enters an expression like 'a1b1+a2b2' (no spaces), and values 1,1,1,1 (for matrix a1) etc., the client sends to Server1 a string in the form of '1,1,1,1;2,2,2,2;+3,3,3,3;4,4,4,4;+'. 例如,如果用户输入一个表达式,例如“ a1b1 + a2b2”(无空格),并且值1,1,1,1(对于矩阵a1)等,则客户端向Server1发送形式为“ 1”的字符串, 1,1,1; 2,2,2,2; +3,3,3,3; 4,4,4,4; +'。 Server1 sends 1,1,1,1;2,2,2,2; Server1发送1,1,1,1; 2,2,2,2; to the computation server. 到计算服务器。 The computation server computes the matrix multiplication of {1,1,1,1} and {2,2,2,2} and returns the result {4,4,4,4} to Server1. 计算服务器计算{1,1,1,1}和{2,2,2,2}的矩阵乘法,并将结果{4,4,4,4}返回到Server1。 Server1 again sends 3,3,3,3;4,4,4,4; Server1再次发送3,3,3,3; 4,4,4,4; to the computation server and so on. 到计算服务器等。 Finally Server1 returns the result of the expression {28,28,28,28} to the client. 最后,Server1将表达式{28,28,28,28}的结果返回给客户端。

My code is as follows: 我的代码如下:

TCPClient.java 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 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 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();
    }
}
}

For execution I start the Computation server first, then Server1 and then the client program. 为了执行,我首先启动计算服务器,然后启动Server1,然后启动客户端程序。

The problem I'm facing is my program works fine for the first client, but if I try to compute this for the second client, the computation server doesn't accept further requests. 我面临的问题是我的程序对于第一个客户端可以正常运行,但是如果我尝试为第二个客户端进行计算,则计算服务器将不接受其他请求。

And if I change my computation server as follows, then it doesn't accept the second token from Server1 (for the first client). 而且,如果我按以下方式更改计算服务器,则它不接受Server1的第二个令牌(对于第一个客户端)。

ComputationServer.java 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

Any help would be much appreciated. 任何帮助将非常感激。 Thanks in advance! 提前致谢!

I assume that "it doesn't work" means that the call from the second client never reaches your ComputationServer . 我假设“它不起作用”意味着来自第二个客户端的调用永远不会到达您的ComputationServer。 Your ComputationServer accepts only one connection, then it loops indefenitly, never enters the accept method again. 您的ComputationServer仅接受一个连接,然后无限循环,再也不会再次输入accept方法。 So why would you expect that your server1 can open a new connection after having got a second request? 那么,为什么您希望您的server1在收到第二个请求后可以打开新连接?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM