Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Java программирование > Общие вопросы по Java, Java SE, Kotlin
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 21.06.2011, 01:08   #1
BRTSBOG
 
Регистрация: 19.11.2009
Сообщений: 5
По умолчанию Сетевой калькулятор

Доброго времени суток и здравия уважаемые форумчане!
Попросила подруга наваять ей САБЖ - т.е. клиент - серверное приложение по протоколу TCP или UDP не критично. Смысл прост - клиент подключается к серверу и вводит числа а потом знак нужной операции (-,+,/,*) Сервер естессно обработывает и посылает результат.
Сразу мне это показалось не очень сложной вещью - мол простой калькулятор я делал - но вот не задача - уперся я лбом в один момент - не понимаю как сделать чтобы формирование той же дейтаграммы шло с вводимых данных???
Код клиента:

Код:
import java.net.*;
import java.io.*;

class ClientUDP
{
		public static void main(String args[])
	{  
	
	BufferedReader stdin = new BufferedReader (new InputStreamReader (System.in));
		 int i=0;
	try{
		for(i=0;i<3;i++){[/COLOR]
		
		DatagramSocket ds=new DatagramSocket(1014);//создаем дейтаграммный сокет клиента, работающий локально по порту 1014
		System.out.println("Vvedi chislo");
		String vybor = stdin.readLine();
		byte serverMes1[]=vybor.getBytes();
		DatagramPacket dp=new DatagramPacket(serverMes1,serverMes1.length,InetAddress.getByName("localhost"),1012);
				
	ds.send(dp);//посылка пакета серверу
	
		ds.close();//закрываем сокет
		}
			}
	catch(Exception e){
		System.out.println("Error "+ e.toString());
	
		}	
			}
Код сервера:
Код:
class ServerUDP
{
	
	
		
	public static void main(String args[])
	{  
	
		 
	try{
		byte clientMessage[]=new byte[30];//массив байт для приема сообщения от клиента
		byte clmess1[]=new byte[30];//message 2 (cifra2)
		byte clmess2[]=new byte [30];//message3 - znak 
		
		//создаем пакет для получения сообщения от клиента. При создании пакета указан порт клиента 1014 (клиент работает по порту 1014, а не 1012 как сервер).
		DatagramPacket dp=new DatagramPacket(clientMessage,clientMessage.length,InetAddress.getByName("localhost"),1014);
		
		//создаем дейтаграммный сокет.Указываем порт сервера 1012, работает он локально
		DatagramSocket ds=new DatagramSocket(1012,InetAddress.getByName("localhost"));
		
		ds.receive(dp);//получаем пакет от клиента
		clientMessage=dp.getData();//вытаскиваем сами данные от клиента в массив байт clientMessage[]
Вот тут то и начинается проблема - как заставить сервер получать от клиента только 3 пакета - 1 число, второе число и знак операции???

Ведь по коду получается что принимаемые данные от клиента присваиваются переменной clientMessage - т.е. фактически мы получим только последнее значение

Тепереь и меня заинтересовала эта тема - хочу знать как это сделать- просто очень интересно.Буду признателен за любую помощь
Спасибо

Последний раз редактировалось Stilet; 26.06.2011 в 18:24.
BRTSBOG вне форума Ответить с цитированием
Старый 21.06.2011, 21:22   #2
netrino
Участник клуба
 
Аватар для netrino
 
Регистрация: 15.07.2008
Сообщений: 1,933
По умолчанию

UDP лучше здесь не использовать, так как он не гарантирует полноценную доставку данных. Плюс, для обмена сообщениями можно использовать более высокоуровневые абстракции, такие как BufferedReader и PrintWriter. Вот, набросал пример, над обработкой входного выражения не заморачивался - сами сделаете.
Код:
import java.net.*;
import java.io.*;

class SocketsUsage {

  public static void main(String[] args) {
    if (args.length > 0)
      if (args[0].equals("server"))
        server();
      else if (args[0].equals("client"))
        client();
  }


  static void client() {

    try {
      BufferedReader userInput = new BufferedReader(new InputStreamReader(System.in));

      System.out.print("Enter the expression: ");
      String expr = userInput.readLine();
      
      if (expr.isEmpty())
        return;

      Socket server = new Socket("localhost", 8192);

      PrintWriter out = new PrintWriter(server.getOutputStream(), true);
      BufferedReader in = new BufferedReader(new InputStreamReader(server.getInputStream()));
    
      System.out.println("Sending `" + expr + "'...");
      out.println(expr);

      String answer = in.readLine();

      System.out.println("answer: " + answer);

      userInput.close();
      in.close();
      out.close();

      server.close();

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

  static void server() {

    try {
      ServerSocket server = new ServerSocket(8192);
      Socket client = server.accept();
      PrintWriter out = new PrintWriter(client.getOutputStream(), true);
      BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));

      String expression = in.readLine().trim();

      System.out.println("We got expression `" + expression + "'. Trying to process...");

      int result = processExpression(expression);
    
      System.out.println("The procession result: " + result);
      
      out.println(result);

      in.close();
      out.close();

      client.close();
      server.close();
    } catch (Exception e) {
      e.printStackTrace();
    }

 }

  static int processExpression(String expr) throws Exception {
    int i = 0;
    
    for (; i < expr.length(); i++) {
      char ch = expr.charAt(i);

      if (!Character.isDigit(ch))
        break;
    }

    int leftOperand = Integer.valueOf(expr.substring(0, i));
    char binaryOperator = 0;

    while (i < expr.length()) {
      char ch = expr.charAt(i);
      i++;
      if (!Character.isWhitespace(ch)) {
        binaryOperator = ch;
        break;
      }
    }

    int rightOperand = Integer.valueOf(expr.substring(i).trim());
    int result = 0;

    switch (binaryOperator) {
      case '-': result = leftOperand - rightOperand; break;
      case '+': result = leftOperand + rightOperand; break;
      case '*': result = leftOperand * rightOperand; break;
      case '/': result = leftOperand / rightOperand; break;
      case '%': result = leftOperand % rightOperand; break;
      default : throw new Exception(" : - ) ");
    }

    return result;
  }
}
Запускать так: java SocketsUsage server для сервера и java SocketsUsage client для клиента.
netrino вне форума Ответить с цитированием
Старый 26.06.2011, 15:08   #3
sashonk
Форумчанин
 
Регистрация: 26.10.2009
Сообщений: 170
По умолчанию

Цитата:
Вот, набросал пример, над обработкой входного выражения не заморачивался - сами сделаете
только прием входящих connections сервер должен выполнять в цикле, а принятые Socket делегировать (например передачей как параметра в конструктор) какому-нибудь другому классу, который собственно занимается выполнением математических операций. Напр
Код:
    while(true)
    try {
        fromclient= servers.accept();

     // класс Manager принимает ссылку на сокет и
      // реализует осуществление мат. операций
      new Manager(fromclient);
    } catch (IOException e) {
          System.exit(-1);
    }
По вашему коду получается, что сервер отрубится после первой обработанной мат операции.
sashonk вне форума Ответить с цитированием
Старый 26.06.2011, 15:18   #4
netrino
Участник клуба
 
Аватар для netrino
 
Регистрация: 15.07.2008
Сообщений: 1,933
По умолчанию

Целью было показать простейший пример обмена данными между сокетами, с расчётом на то, что автор сам додумается положить приём сообщений в цикл, а клиент, сервер и парсер мат. выражений в отдельные классы, как того требует парадигма ООП.
netrino вне форума Ответить с цитированием
Старый 26.06.2011, 16:29   #5
sashonk
Форумчанин
 
Регистрация: 26.10.2009
Сообщений: 170
По умолчанию

ну а вдруг не догадается
sashonk вне форума Ответить с цитированием
Старый 17.09.2012, 14:08   #6
Painkiller-101
Новичок
Джуниор
 
Регистрация: 17.09.2012
Сообщений: 1
По умолчанию

Цитата:
Сообщение от netrino Посмотреть сообщение
Целью было показать простейший пример обмена данными между сокетами, с расчётом на то, что автор сам додумается положить приём сообщений в цикл, а клиент, сервер и парсер мат. выражений в отдельные классы, как того требует парадигма ООП.
Цитата:
Сообщение от sashonk Посмотреть сообщение
ну а вдруг не догадается
Сейчас стоит задача с сетевым калькулятором.
Не могли бы подробнее растолковать, что и где должно находиться...
Уровня к сожалению пока не хватает, чтобы самому доработать написанное
Painkiller-101 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Сетевой принтер Evgewa Работа с сетью в Delphi 0 12.07.2010 20:11
сетевой фильтр Betty Компьютерное железо 3 02.07.2009 17:47
Сетевой график Nina+ Помощь студентам 10 16.05.2009 11:13
Сетевой тест Stanislav Работа с сетью в Delphi 3 29.12.2007 01:37