Многопоточный сервер с использованием TCP в Java - PullRequest
0 голосов
/ 22 июля 2011

Я пытаюсь реализовать простое TCP-соединение между клиентом и сервером. Я сделал Сервер многопоточным, чтобы он мог принимать несколько запросов (например, найти сумму, максимум, минимум строки чисел, предоставленных пользователем) от одного клиента или принимать несколько соединений от разных клиентов. Я запускаю их оба на своей машине, но сервер, похоже, не выдвигает ответ. Не уверен, что я здесь не так делаю -

public final class CalClient {

static final int PORT_NUMBER = 6789;  

public static void main (String arg[]) throws Exception
{
    String serverName;
    @SuppressWarnings("unused")
    String strListOfNumbers = null;
    int menuIndex;
    boolean exit = false;

    BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));

    System.out.println("Please enter host name...");
    System.out.print("> ");
    serverName = inFromUser.readLine();

    Socket clientSocket = new Socket(serverName, PORT_NUMBER);
    DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
    BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

    //outToServer.writeBytes(serverName + '\n');

    System.out.println("");
    System.out.println("Enter 1 to enter the list of numbers");
    System.out.println("Enter 2 to perform Summation");
    System.out.println("Enter 3 to calculate Maximum");
    System.out.println("Enter 4 to calculate Minimum");
    System.out.println("Enter 5 to Exit");

    while (!exit) {
        System.out.print(">");
        menuIndex = Integer.parseInt(inFromUser.readLine());

        if (menuIndex == 1) {   
            System.out.println("Please enter the numbers separated by commas.");
            System.out.print(">");
            strListOfNumbers = inFromUser.readLine();
            outToServer.writeBytes("List" + strListOfNumbers);
            //continue;
        }
        else if (menuIndex == 2) {
            outToServer.writeBytes("SUM");
            System.out.println(inFromServer.readLine());
        }
        else if (menuIndex == 3) {
            outToServer.writeBytes("MAX");
            System.out.println(inFromServer.readLine());
        }
        else if (menuIndex == 4) {
            outToServer.writeBytes("MIN");
            System.out.println(inFromServer.readLine());
        }
        else if (menuIndex == 5) {
            outToServer.writeBytes("EXIT");
            exit = true;
        }
    }
}

}

public final class CalServer 
{

      static final int PORT_NUMBER = 6789;  

public static void main(String[] args) throws IOException 
{
    try {
        ServerSocket welcomeSocket = new ServerSocket(PORT_NUMBER);
        System.out.println("Listening");
        while (true) {
            Socket connectionSocket = welcomeSocket.accept();

            if (connectionSocket != null) {
                CalRequest request = new CalRequest(connectionSocket);
                Thread thread = new Thread(request);
                thread.start();
            }
        }
    } catch (IOException ioe) {
        System.out.println("IOException on socket listen: " + ioe);
        ioe.printStackTrace();
    }
}
}

final class CalRequest implements Runnable
{
Socket socket;
BufferedReader inFromClient;
DataOutputStream outToClient;

TreeSet<Integer> numbers = new TreeSet<Integer>();
int sum = 0;

public CalRequest(Socket socket)
{
    this.socket = socket;
}

@Override
public void run() 
{
    try {
        inFromClient = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
        outToClient = new DataOutputStream(socket.getOutputStream());

        while(inFromClient.readLine()!= null) {
            processRequest(inFromClient.readLine());
        }       

    } catch (IOException e) {
        e.printStackTrace();
    }
}

public void processRequest(String string) throws IOException
{
    String strAction = string.substring(0,3);

    if (strAction.equals("LIS")) {
        String strNumbers = string.substring(5);
        String[] strNumberArr;
        strNumberArr = strNumbers.split(",");

        // convert each element of the string array to type Integer and add it to a treeSet container. 
        for (int i=0; i<strNumberArr.length; i++)
            numbers.add(new Integer(Integer.parseInt(strNumberArr[i])));
    }
    else if (strAction.equals("SUM")) {
        @SuppressWarnings("rawtypes")
        Iterator it = numbers.iterator();
        int total = 0;

        while (it.hasNext()) {
            total += (Integer)(it.next());
        }
    }
    else if (strAction.equals("MAX")) {
        outToClient.writeBytes("The max is: " + Integer.toString(numbers.last()));
    }
    else if (strAction.equals("MIN")) {
        outToClient.writeBytes("The max is: " + Integer.toString(numbers.first()));
    }
}

}

Ответы [ 2 ]

1 голос
/ 26 апреля 2012

Мой опыт работы с TCP-сокетами использует исключительно данные ASCII, и мой код отражает это, я верю.Если это так, вы можете попробовать это:

Сначала попробуйте создать экземпляр ваших потоков данных следующим образом:

socket     = new Socket (Dest, Port);
toServer   = new PrintWriter (socket.getOutputStream(), true);
fromServer = new BufferedReader (new InputStreamReader
    (socket.getInputStream()), 8000);

Значение true в конце, конструктор printWriter сообщает этоавтоматическая очистка (прекрасный термин) буфера при выдаче println.

Когда вы фактически используете сокет, используйте следующее:

toServer.println (msg.trim());
resp = fromServer.readLine().trim();

Мне не нужно добавлять \ nсам с исходящим текстом, но это может быть связано с моей конкретной ситуацией (подробнее об этом ниже).Входящие данные должны иметь \ n в конце, иначе readLine не работает.Я предполагаю, что есть способы, которыми вы можете читать из байта сокета побайтно, но также и то, что код будет не таким уж простым.

К сожалению, TCP-сервер, с которым я общаюсь, - это программа C ++, поэтомумы гарантируем, что \ n присутствует во входящих данных, не будет работать для вас (и может не понадобиться в исходящих данных).

Наконец, если это поможет, я построил свой код на основе этоговеб-пример:

http://content.gpwiki.org/index.php/Java:Tutorials:Simple_TCP_Networking

Редактировать: я нашел другой пример кода, который использует DataOutputStream ... Возможно, вы найдете его полезным, если вы его еще не видели.

http://systembash.com/content/a-simple-java-tcp-server-and-tcp-client/

1 голос
/ 22 июля 2011

Поскольку вы используете readLine(), я полагаю, что вам действительно нужно отправить терминаторы строки.

...