Вопрос по С++

Cris

Member
еще один вопрос: есть ли возможно сделать асинхронные ввод/вывод на с++,
ввод и вывод не с файлами, а ввод с клавы, вывод на экран? тоесть я хочю написать сервер который будет работать без создания других потоков - то есть все операции с сокетами в асинхронном режиме я вроде как разобрал, а вот ввод команд серверу как сделать чтоб не помешать обработке остально хз

я вроде нашол что то похожее с вводом но оно сильно громоздкое и для меня еще не понятное... и вроде это даже не то что надо мне)
:
Код:
// =====================================================
	// Работа с асинхронным адаптером COM1.
	// Перед запуском программы необходимо замкнуть
	// контакты 2 и 3 разъема COM1
	//
	// (C) Фролов А.В, 1997
	//
	// E-mail: frolov@glas.apc.org
	// WWW:    http://www.glasnet.ru/~frolov
	//            или
	//         http://www.dials.ccas.ru/frolov
	// =====================================================
	
	#include <stdio.h>
	#include <conio.h>
	
	typedef struct _AUX_MODE_ 
	{
	  union 
	  {
	    struct 
	    {
	      unsigned char len : 2, // длина символа
	           stop         : 1, // число стоп-битов
	           parity       : 2, // контроль четности
	           stuck_parity : 1, // фиксация четности
	           en_break_ctl : 1, // установка перерыва
	           dlab         : 1; // загрузка регистра делителя
	    } ctl_word;
	    char ctl;
	  } ctl_aux;
	  unsigned long baud; // скорость передачи данных
	} AUX_MODE;
	
	void aux_stat(AUX_MODE *mode, int port);
	int aux_init(AUX_MODE *mode, int port, int imask);
	void aux_outp(char chr, int port);
	char aux_inp(int port);
	
	int main(void) 
	{
	  AUX_MODE amd;
	
	  aux_stat(&amd, 0);
	  printf("\nСостояние порта COM1:"
	    "\nКод длины символа:    %d"
	    "\nКод числа стоп-битов: %d"
	    "\nКонтроль четности:    %d"
	    "\nСкорость передачи:    %lu",
	    amd.ctl_aux.ctl_word.len,
	    amd.ctl_aux.ctl_word.stop,
	    amd.ctl_aux.ctl_word.parity,
	    (unsigned long)amd.baud);
	
	  amd.baud = 115200;
	  aux_init(&amd, 0, 0);
	
	  aux_stat(&amd, 0);
	  printf("\nСостояние порта COM1:"
	    "\nКод длины символа:    %d"
	    "\nКод числа стоп-битов: %d"
	    "\nКонтроль четности:    %d"
	    "\nСкорость передачи:    %lu",
	    amd.ctl_aux.ctl_word.len,
	    amd.ctl_aux.ctl_word.stop,
	    amd.ctl_aux.ctl_word.parity,
	    (unsigned long)amd.baud);
	
	  printf("\n\nТестирование асинхронного адаптера."
	    "\nНажимайте клавиши!"
	    "\nДля завершения работы нажмите <Contril+C>\n");
	
	  for(;;) 
	  {
	    // Вводим символ с клавиатуры и передаем его
	    // в асинхронный адаптер
	    aux_outp((char)getch(), 0);
	
	    // Вводим символ из асинхронного адаптера и
	    // отображаем его на экране
	    putchar(aux_inp(0));
	  }
	  return 0;
	}
	
	/**
	*.Name         aux_stat
	*.Title        Определение режима асинхронного адаптера
	*
	*.Descr        Эта функция считывает текущий режим
	*              асинхронного порта и записывает его
	*              в структуру с типом AUX_MODE
	*
	*.Proto        void aux_stat(AUX_MODE *mode, int port);
	*
	*.Params       AUX_MODE mode - структура, описывающая
	*              протокол и режим работы порта:
	*
	*              int port - номер асинхронного адаптера:
	*                 0 - COM1, 1 - COM2
	**/
	void aux_stat(AUX_MODE *mode, int port) 
	{
	  unsigned long b;
	
	  // Запоминаем режим адаптера
	  mode->ctl_aux.ctl = (char)inp(0x3fb - 0x100 * port);
	
	  // Устанавливаем старший бит режима
	  // для считывания текушей скорости передачи
	  outp(0x3fb - 0x100 * port, mode->ctl_aux.ctl | 0x80);
	
	  // Считываем значение регистра делителя
	  b = inp(0x3f9 - 0x100 * port); b = b << 8;
	  b += inp(0x3f8 - 0x100 * port);
	
	  // Преобразуем его в боды
	  switch (b) 
	  {
	    case 1040: b = 110; break;
	    case 768: b = 150; break;
	    case 384: b = 300; break;
	    case 192: b = 600; break;
	    case 96: b = 1200; break;
	    case 48: b = 2400; break;
	    case 24: b = 4800; break;
	    case 12: b = 9600; break;
	    case 6: b = 19200; break;
	    case 3: b = 38400; break;
	    case 2: b = 57600; break;
	    case 1: b = 115200; break;
	    default: b=0; break;
	  }
	
	  mode->baud = b;
	
	  // Восстанавливаем состояние адаптера
	  outp(0x3fb - 0x100 * port, mode->ctl_aux.ctl & 0x7f);
	}
	
	/**
	*.Name         aux_init
	*.Title        Инициализация асинхронного адаптера
	*
	*.Descr        Эта функция инициализирует асинхронные
	*              адаптеры, задавая протокол обмена данными
	*              и скорость обмена данными
	*
	*.Proto        int aux_init(AUX_MODE *mode, int port,
	*                                        int imask);
	*
	*.Params       AUX_MODE *mode - указатель на структуру,
	*                        описывающую протокол и режим работы 
	*                        порта;
	*
	*              int port - номер асинхронного адаптера:
	*                 0 - COM1, 1 - COM2
	*
	*              int imask - значение для регистра маски
	*                          прерываний
	*
	*.Return       0 - инициализация выполнена успешно;
	*              1 - ошибки в параметрах инициализации.
	**/
	int aux_init(AUX_MODE *mode, int port, int imask) 
	{
	  unsigned div;
	  char ctl;
	
	  // Вычисляем значение для делителя
	  switch (mode->baud) 
	  {
	    case 110: div = 1040; break;
	    case 150: div = 768; break;
	    case 300: div = 384; break;
	    case 600: div = 192; break;
	    case 1200: div = 96; break;
	    case 2400: div = 48; break;
	    case 4800: div = 24; break;
	    case 9600: div = 12; break;
	    case 19200: div = 6; break;
	    case 38400: div = 3; break;
	    case 57600: div = 2; break;
	    case 115200: div =1; break;
	    default: 
	      return(-1); break;
	  }
	
	  // Записываем значение делителя частоты
	  ctl = inp(0x3fb - 0x100 * port);
	  outp(0x3fb - 0x100 * port, ctl | 0x80);
	
	  outp(0x3f9 - 0x100 * port, (div >> 8) & 0x00ff);
	  outp(0x3f8 - 0x100 * port, div & 0x00ff);
	
	  // Записываем новое управляющее слово
	  outp(0x3fb - 0x100 * port, mode->ctl_aux.ctl & 0x7f);
	
	  // Устанавливаем регистр управления прерыванием
	  outp(0x3f9 - 0x100 * port, imask);
	  
	  return 0;
	}
	
	/**
	*.Name         aux_outp
	*.Title        Вывод символа в асинхронный адаптер
	*
	*.Descr        Эта функция дожидается готовности
	*              передатчика и посылает символ
	*
	*.Proto        void aux_outp(char chr, int port);
	*
	*.Params       char chr - посылаемый символ;
	*
	*              int port - номер асинхронного адаптера:
	*                 0 - COM1, 1 - COM2
	**/
	void aux_outp(char chr, int port) 
	{
	  unsigned status_reg, out_reg;
	
	  status_reg = 0x3fd - 0x100 * port;
	  out_reg = status_reg - 5;
	
	  while( (inp(status_reg) & 0x20) == 0 );
	  outp(out_reg, chr);
	}
	
	/**
	*.Name         aux_inp
	*.Title        Ввод символа из асинхронного адаптера
	*
	*.Descr        Эта функция дожидается готовности
	*              приемника и вводит символ из асинхронного
	*              адаптера
	*
	*.Proto        char aux_inp(int port);
	*
	*.Params       int port - номер асинхронного адаптера:
	*                 0 - COM1, 1 - COM2
	*
	*.Return       Принятый символ
	**/
	char aux_inp(int port) 
	{
	  unsigned status_reg, inp_reg;
	
	  status_reg = 0x3fd - 0x100 * port;
	  inp_reg = status_reg - 5;
	
	  while( (inp(status_reg) & 1) == 0 );
	  return(inp(inp_reg));
	}
 

dreamer

Member
еще один вопрос: есть ли возможно сделать асинхронные ввод/вывод на с++,
ввод и вывод не с файлами, а ввод с клавы, вывод на экран? тоесть я хочю написать сервер который будет работать без создания других потоков - то есть все операции с сокетами в асинхронном режиме я вроде как разобрал, а вот ввод команд серверу как сделать чтоб не помешать обработке остально хз
А чем тебе не угодили потоки?
По-хорошему при создании сервера команды ему отдаются через те же сокеты. Т.е. сервер не принимает никакого ввода с клавы а создается спецклиент (или этот функционал добавляется в обычные клиенты) для управления сервером. Это хорошо еще и потому что сервер может быть запущен на удаленной машине а управляться с локальной.
В таком случае конечно нужно предусмотреть авторизацию в протоколе общения.
 

Cris

Member
А чем тебе не угодили потоки?
По-хорошему при создании сервера команды ему отдаются через те же сокеты. Т.е. сервер не принимает никакого ввода с клавы а создается спецклиент (или этот функционал добавляется в обычные клиенты) для управления сервером. Это хорошо еще и потому что сервер может быть запущен на удаленной машине а управляться с локальной.
В таком случае конечно нужно предусмотреть авторизацию в протоколе общения.
та чета в голову взбрело насчет потоков))

насчет удаленного управления это я вообше забыл))
кстати а как выполнить команду restart для приложения? тоесть само себя перезапустило, или делать так: закрываем все сокеты, файлы, соеденения вызываем процес этойже программы и делаем exit? закрывать все соеденения чтоб новая копия невызвала конфликты?

кстати как определить ефективное количество потоков для работы сервера, так как в асинхронном режиме можна и 1000 юзеров запхнуть на 1 поток а можно и на 10 по 100 юзеров, но и ненадо 100 потоков чтоб комп лагать начал)) или делать както количество ядер компа = кол потоков/процесов?
 
Останнє редагування:

dreamer

Member
та чета в голову взбрело насчет потоков))

насчет удаленного управления это я вообше забыл))
кстати а как выполнить команду restart для приложения? тоесть само себя перезапустило, или делать так: закрываем все сокеты, файлы, соеденения вызываем процес этойже программы и делаем exit? закрывать все соеденения чтоб новая копия невызвала конфликты?

кстати как определить ефективное количество потоков для работы сервера, так как в асинхронном режиме можна и 1000 юзеров запхнуть на 1 поток а можно и на 10 по 100 юзеров, но и ненадо 100 потоков чтоб комп лагать начал)) или делать както количество ядер компа = кол потоков/процесов?
Насчет перезапуска наверное так, не сталкивался, это бывает необходимо нечасто.
Насчет одновременного числа обслуживаемых подключений обычно это задается настройками программы и вычисляется исходя из экспериментов -- если процесс сильно нагружает комп можно уменьшить это число.
 

TraNceR

Member
А зачем перезапускать процесс? Полностью все передаешь и заново запускаешь, жтого вполне достаточно например для импользования новых параметров в конфиге имхо.
 

Cris

Member
А зачем перезапускать процесс? Полностью все передаешь и заново запускаешь, жтого вполне достаточно например для импользования новых параметров в конфиге имхо.
можеш расшифровать "Полностью все передаешь и заново запускаешь", я просто хочю для сервера сделать команду restart

кстати а может мне хтото расказать вкраце как сделать систему обновления: клиент конектиться к серву, получает например список файлом и их md5 код, проверяет по своим и если есть несовпадения закачивает, но как сделать чтобы он мог закачать так сказать сам себя и перезапуститься, тоесть заменить собственный файл?
 

Cris

Member
вопрос вопшемно по C++ Builder: как можно сделать чтото типа такого -
если веб камеру использует другая программа то нужно чтобы копия изображения записывалась и мне, если камеру не что не использует то ломиться на прямую к ней, но если другая программа начнет ее тоже допытываться то перейти в первый режим - пасивный, как это можно сделать и можно ли воопше?
 

dreamer

Member
вопрос вопшемно по C++ Builder: как можно сделать чтото типа такого -
если веб камеру использует другая программа то нужно чтобы копия изображения записывалась и мне, если камеру не что не использует то ломиться на прямую к ней, но если другая программа начнет ее тоже допытываться то перейти в первый режим - пасивный, как это можно сделать и можно ли воопше?
Очень уж узкий вопрос, лучше бы ты создал отдельную тему, а про работу с камерами через WinAPI ты читал?
 

Cris

Member
Очень уж узкий вопрос, лучше бы ты создал отдельную тему, а про работу с камерами через WinAPI ты читал?
вроде как почитывал, но если хто на словах раскажет будет понятней)
ну вроде нашол хороший сайт который понятно на русском описует directshow, но меня больше волнует другйо вопрос - смогу ли я подсоедениться какими либо методами к вебкамере которая уже работает с другим приложением?
 
Останнє редагування:
Собственно вопросик по передаче массива в функцию.

#include <stdio.h>
#define Ax 2
#define Ay 7
#define Bx 1
#define By 4

void vvod(int z[], int n, int m, char q);

void main(void)
{
int a[Ax][Ay], min, numi, numj;
vvod(a, Ax, Ay, 'a');
vvod(b, Bx, By, 'b');


На строку vvod(a, Ax, Ay, 'a'); и vvod(b, Bx, By, 'b');
идет ругательство:
Cannot convert 'int [7] _ss' to 'int *'
Type mismatch in parameter 'z' in call to 'vvod(int *, int, int, char)'
Cannot convert 'int [4] _ss' to 'int *'
Type mismatch in parameter 'z' in call to 'vvod(int *, int, int, char)'


Если бы хотя бы Ay и By были равны, то можно было бы записать:
void vvod(int z[][X], int n, int m, char q);

Но как быть если же количество столбцов двумерного массива разные?
 
Зверху