Модераторы: feodorv

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Отправка по tcp для начинающего 
:(
    Опции темы
nullpoint
Дата 1.8.2014, 18:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 4.6.2013

Репутация: нет
Всего: нет



Всем привет. Прошу объяснить все в подробностях для дурака.
Такая задача стоит. Есть TCP сервер и клиент. 
Клиент присылает серверу сообщение msgCli, в котором первый байт - команда серверу (например, 0х15), затем 5 байт - ASCII строка с "\0".
Сервер в ответ отправляет сообщение msgServ: 1й байт - команда (например, 0х45), 2й байт - команда (например, 0х42),затем 3 байта ASCII строка с "\0", затем 9 байт сообщение. Эти 9 байт получаются следующим образом: 
Код

unsigned char msgRand[9];
int fd;
fd = open("/dev/random", O_RDONLY);
read(fd, msgRand, 9);

Теперь перед отправкой мы должны отобразить на экранmsgRand в ASCII, а отправить в десятичном виде, т.е. на экран вот в таком виде показываем - 4da234f199a5bce8c1, а отправляем - 7716252241153165188232193 (данные значения взяты просто для примера).

Собственно я не могу сообразить как msgRand перевести в эти два представления. Потом собрать две команды по 1 байту, ASCII строку, считанные 9 байт в одно сообщение и отправить.

P.S. Это не лабораторка. Просто учусь программировать. Хотелось бы разобраться с этим. Использую Ubuntu 14.04 + QtCreator(Qt 4.7).
PM MAIL   Вверх
feodorv
Дата 1.8.2014, 19:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 10
Всего: 45



Я запутался.
Цитата(nullpoint @  1.8.2014,  19:14 Найти цитируемый пост)
а отправить в десятичном виде

и 
Цитата(nullpoint @  1.8.2014,  19:14 Найти цитируемый пост)
затем 9 байт сообщение

никак друг с другом не сочетаются.


Цитата(nullpoint @  1.8.2014,  19:14 Найти цитируемый пост)
как msgRand перевести в эти два представления

Откуда тогда у Вас пример для 4da234f199a5bce8c1 => 7716252241153165188232193?


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
_zorn_
Дата 1.8.2014, 19:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1077
Регистрация: 21.8.2007

Репутация: нет
Всего: 12



Есть такое подозрение, что школьник хочет замутить свой ботнет. С блекджеком соответственно.
PM MAIL   Вверх
nullpoint
Дата 1.8.2014, 21:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 4.6.2013

Репутация: нет
Всего: нет



_zorn_, да не нужен мне ботнет, тем более с моими навыками я его буду писать лет 100:)


feodorv, про десятичный вид я скорее всего неправильно выразился.

Цитата(feodorv @  1.8.2014,  19:32 Найти цитируемый пост)
Откуда тогда у Вас пример для 4da234f199a5bce8c1 => 7716252241153165188232193?

Считал из /dev/random 9 байт, затем вывел:
Код

unsigned int intValue[9];
for (int i = 0; i < 9; i++)
{
    intValue[i] = (unsigned int)msgRand[i];
    printf("%u", intValue[i]); //вот в таком виде должен отправить данные клиенту
 }
for (int j = 0; j < 9; j++)
    printf("%x",msgRand[i]); //вот в таком виде я должен показать на экран

"Интовое" представление нужно записать в базу данных, чтобы при следующем запуске приложения, если не были считаны новые 9 байт, отобразить на экран и отправить клиенту предыдущее значение.

Это сообщение отредактировал(а) nullpoint - 1.8.2014, 21:28
PM MAIL   Вверх
feodorv
Дата 1.8.2014, 22:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 10
Всего: 45



Цитата(nullpoint @  1.8.2014,  22:25 Найти цитируемый пост)
затем вывел

Вот не за что не догадался бы)))


Цитата(nullpoint @  1.8.2014,  22:25 Найти цитируемый пост)
"Интовое" представление нужно записать в базу данных, чтобы при следующем запуске приложения, если не были считаны новые 9 байт, отобразить на экран и отправить клиенту предыдущее значение.

"Интовое" представление не однозначное, восстановить из него однозначно первоначальные 9 байт, скорее всего, не удастся, если не потребовать 3 "интовых" символа на один первоначальный. Но, честно говоря, я не вижу вообще никаких предпосылок для того, чтобы по сети гонять, а затем сохранять в базе, именно "интовое" представление в противовес оригинальному, девятибайтовому.


Вы всегда можете сделать что-то в этом роде:
Код

char buf[128];
snprintf( buf, sizeof(buf), "%u%u%u%u%u%u%u%u%u", msgRand[0], msgRand[1], msgRand[2], msgRand[3], msgRand[4], msgRand[5], msgRand[6], msgRand[7], msgRand[8]);

Особого смысла в этом нет, но дело Ваше)))


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
nullpoint
Дата 1.8.2014, 22:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 4.6.2013

Репутация: нет
Всего: нет



feodorv, подскажите тогда как правильно сделать. Как это все передать одним сообщением "1й байт(0x45)2й байт(0x42)3 байта(ASCII с \0)9 байт(msgRand)"? И как принять от клиента сообщение и разобрать его на части?


Можно же вроде вот так сделать:
Код

unsigned int a = *(unsigned int*)msgRand;
unsigned int b = *(unsigned int*)(msgRand+4);

И записать это в два поля БД, но вот как потом это все обратно восстановить в единое целое?

Это сообщение отредактировал(а) nullpoint - 1.8.2014, 22:58
PM MAIL   Вверх
feodorv
Дата 2.8.2014, 07:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 10
Всего: 45



Цитата(nullpoint @  1.8.2014,  23:51 Найти цитируемый пост)
Как это все передать одним сообщением

Как обычно:
Код

unsigned char message[14];
message[0] = 0x45u;
message[1] = 0x42u;
message[2] = '\0';
message[3] = '\0';
message[4] = '\0';
message[5] = msgRand[0];
message[6] = msgRand[1];
message[7] = msgRand[2];
message[8] = msgRand[3];
message[9] = msgRand[4];
message[10] = msgRand[5];
message[11] = msgRand[6];
message[12] = msgRand[7];
message[13] = msgRand[8];
send( socket, message, 14, 0);



Цитата(nullpoint @  1.8.2014,  23:51 Найти цитируемый пост)
И как принять от клиента сообщение

Здесь немного сложнее, так как целостное 14-байтовое сообщение может быть разбито протоколом TCP (что маловероятно, но возможно) на несколько пакетов, которые читаются отдельными recv:
Код

unsigned char response[14];
int length = 0;
while( length < 14 )
{
  int n = recv( socket, &response[length], 14-length, 0);

  if( n == 0 ) // соединение закрыто
  {
    length = 0;
    break;
  }

  if( n < 0 ) // произошла ошибка
  {
    length = -1;
    break;
  }

  length += n;
}



Цитата(nullpoint @  1.8.2014,  23:51 Найти цитируемый пост)
и разобрать его на части?

Аналогично:
Код

command1 = response[0];
command2 = response[1];
//...
msgRand[0] = response[5];
msgRand[1] = response[6];
msgRand[2] = response[7];
msgRand[3] = response[8];
msgRand[4] = response[9];
msgRand[5] = response[10];
msgRand[6] = response[11];
msgRand[7] = response[12];
msgRand[8] = response[13];



Цитата(nullpoint @  1.8.2014,  23:51 Найти цитируемый пост)
Можно же вроде вот так сделать:

Девятый байт пропал. Или он не нужен?
Вроде, у баз данных должен быть тип поля "сырые данные", в которое можно запихнуть произвольные данные заданной длинны. Да и текстовое поле (длинной 9 символов) у некоторых БД позволяет хранить произвольные символы, не только отображаемые на экране. Ну и в крайнем случае храните эти 9 символов в 16-ричном виде в текстовом поле длины 18, из 16-ричного вида всегда можно восстановить исходный 9-байтовый вид...


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
nullpoint
Дата 2.8.2014, 09:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 4.6.2013

Репутация: нет
Всего: нет



feodorv,  я жутко извиняюсь,  не объяснил все до конца, поэтому и возникла небольшая путаница. :(
Считывая из /dev/random, я таким образом генерирую ключ для клиента, т.е. мне как раз таки не нужны "сырые" байты, а нужно случайно сгенерированное число. Т.е. считанные байты я перевожу в unsigned int (7716252241153165188232193) и его отправляю клиенту, а на экран я должен вывести этот ключ в виде ASCII (4da234f199a5bce8c1). И вот тут у меня начинаются проблемы. 


Цитата(feodorv @  2.8.2014,  07:42 Найти цитируемый пост)
Девятый байт пропал

Точно, даже не обратил внимания, что только 8 байт записал.


Цитата(feodorv @  2.8.2014,  07:42 Найти цитируемый пост)
message[2] = '\0';message[3] = '\0';message[4] = '\0';

Я имел в виду что строка ASCII с завершающим \0, а не вся она состоит из \0 smile т.е. "abc\0"
PM MAIL   Вверх
nullpoint
Дата 2.8.2014, 10:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 4.6.2013

Репутация: нет
Всего: нет



Схематично сообщения клиента и сервера выглядят так:
 user posted image

Это сообщение отредактировал(а) nullpoint - 2.8.2014, 10:09
PM MAIL   Вверх
feodorv
Дата 2.8.2014, 10:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 10
Всего: 45



Цитата(nullpoint @  2.8.2014,  10:51 Найти цитируемый пост)
Я имел в виду что строка ASCII с завершающим \0, а не вся она состоит из \0 smile т.е. "abc\0" 

Это сильно меняет ситуацию? Ну будет сообщение длиной 15 байт...


Цитата(nullpoint @  2.8.2014,  10:51 Найти цитируемый пост)
мне как раз таки не нужны "сырые" байты, а нужно случайно сгенерированное число

Всё равно не понятно, что Вам нужно. Хотите гонять "интовый" вид своих 9 байт - гоняйте, я не настаиваю, хотя этот самый "интовый" вид можно получить и на стороне клиента из сырых 9 байт. Делайте, как Вам угодно. Только тогда в формат сообщения Вы должны будете добавить длину сообщения, так как "интовое" представление не обладает фиксированной длиной (в отличие от сырого вида) (либо хитрый однократный обмен сообщениями с правильными shutdown( socket, SD_SEND)). Да и о "случайности" в таком виде можно говорить лишь условно.


Как получить "интовую" строчку я уже писал:
Цитата(feodorv @  1.8.2014,  23:17 Найти цитируемый пост)
char buf[128];
snprintf( buf, sizeof(buf), "%u%u%u%u%u%u%u%u%u", msgRand[0], msgRand[1], msgRand[2], msgRand[3], msgRand[4], msgRand[5], msgRand[6], msgRand[7], msgRand[8]);

Аналогично получается "шестнадцатиричная" строка:
Код

snprintf( buf, sizeof(buf), "%x%x%x%x%x%x%x%x%x", msgRand[0], msgRand[1], msgRand[2], msgRand[3], msgRand[4], msgRand[5], msgRand[6], msgRand[7], msgRand[8]);
(если не беспокоиться о числе строковых символов на один сырой байт).


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
nullpoint
Дата 2.8.2014, 11:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 4.6.2013

Репутация: нет
Всего: нет



feodorv, да я совсем запутался с этими вещами и поэтому не могу нормально объяснить, что нужно...

Давайте я опишу лучше какую я задачу поставил себе, а вы подскажите как бы вы ее решили. Наверное, так будет лучше.

Клиент присылает серверу команду (или 0х45, или 0х44) и ASCII строку с завершающим \0, каждый клиент присылает свою строку, которая не меняется, своего рода идентификатор. Сервер смотрит какую команду прислал клиент и в зависимости от команды или высылает ответ (если 0х45) или выводит на экран сообщение (если 0х44). В ответ клиенту он отсылает команду 0х45, команду 0х42, ASCII строку с \0 (3 байта), ключ (9 байт). Когда сервер принял сообщение и "увидел" что команда равна 0х45, он начинает искать в базе присланную ASCII строку, если нашел, то генерирует ключ 9 байт, отображает его на экран в виде ASCII кодов, т.е. выводит 18 символов 4da234f199a5bce8c1, и затем отправляет ключ клиенту в таком виде 0х450х42abc\07716252241153165188232193. Перед отправкой ключ записывается в БД, чтобы при следующем запуске программы, если не сгенерирован новый ключ отправить его клиенту и вывести на экран в ASCII.
PM MAIL   Вверх
feodorv
Дата 2.8.2014, 11:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 10
Всего: 45



Итак, имеем однократный обмен сообщениями.

сервер
При подключении клиента сервер делает recv на 5(???) байт, которые клиент обязан прислать в течении некоторого времени (если не прислал, соединение сервером закрывается). По получении этих 5 байт сервер делает:
  • если команда 0х45, то по строчке в запросе ищем в базе данных идентификатор клиента. Если не нашли, то что? Если нашли, то смотрим на ключ. Если ключ не сгенерирован, то генерируем ключ, сохраняем в БД. В ответ шлём клиенту ключ. (Ключ возможно ли перегенерировать?)
  • если команда 0х44, то на экран выводим какое-то сообщение. (Какое?)
  • если другая команда, то что?

клиент
Подключается к серверу и шлёт 5-ти байтовый запрос. Если запрос с командой 0х45, то ждёт ответа неопределенной длины с ключом.

Так?

Зачем клиенту "интовое" представление? Что он будет с ним делать?

В чем сложность?


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
nullpoint
Дата 2.8.2014, 11:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 4.6.2013

Репутация: нет
Всего: нет



Цитата(feodorv @  2.8.2014,  11:29 Найти цитируемый пост)
Если не нашли, то что? 

Просто выводим сообщение об ошибке.

Цитата(feodorv @  2.8.2014,  11:29 Найти цитируемый пост)
Если нашли, то смотрим на ключ.

Если нашли то отсылаем клиенту ключ из БД. Лучше наверное сначала сгенерировать ключ и записать его в БД и уже потом брать его оттуда и отправлять. А новый ключ генерировать по какому-нибудь другому событию (это не главное).

Цитата(feodorv @  2.8.2014,  11:29 Найти цитируемый пост)
выводим какое-то сообщение. (Какое?)

Неважно, любое. Можно написать что ошибка клиента.

Цитата(feodorv @  2.8.2014,  11:29 Найти цитируемый пост)
если другая команда, то что?

Ничего не делать, ну или можно вывести сообщение об ошибке.

Цитата(feodorv @  2.8.2014,  11:29 Найти цитируемый пост)
Зачем клиенту "интовое" представление? Что он будет с ним делать?

Это значит мои непонятки пошли. Я думал что если мы отсылаем ключ, то это должно быть какое-то значение, а не непонятный набор печатных и непечатных символов.


Цитата(feodorv @  2.8.2014,  11:29 Найти цитируемый пост)
В чем сложность?

Как записать ключ в базу. Запросы я могу сделать. Проблема в том в каком виде он туда запишется и чтобы нормально его потом оттуда можно было взять. Как проверять есть ли в базе присланный клиентом идентификатор? Не буду же я последовательно каждый элемент массива сравнивать с символом строки идентификатора из базы.
PM MAIL   Вверх
feodorv
Дата 2.8.2014, 12:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 10
Всего: 45



Цитата(nullpoint @  2.8.2014,  12:51 Найти цитируемый пост)
Лучше наверное сначала сгенерировать ключ и записать его в БД и уже потом брать его оттуда и отправлять.

Тогда при каждом обращении клиента для него будет сгенерирован новый ключ. Вы этого добиваетесь?


Цитата(nullpoint @  2.8.2014,  12:51 Найти цитируемый пост)
а не непонятный набор печатных и непечатных символов

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


Цитата(nullpoint @  2.8.2014,  12:51 Найти цитируемый пост)
Как записать ключ в базу.

Всё зависит от того, какую БД Вы хотите использовать. Для данной задачи вполне подойдет какая-нибудь btree, либо самописный текстовый файл, который грузится в бинарное дерево при старте сервера.


Цитата(nullpoint @  2.8.2014,  12:51 Найти цитируемый пост)
Проблема в том в каком виде он туда запишется и чтобы нормально его потом оттуда можно было взять.

Это вопрос к БД. И даже в другую ветку smile 


Цитата(nullpoint @  2.8.2014,  12:51 Найти цитируемый пост)
Как проверять есть ли в базе присланный клиентом идентификатор?

Идентификатор клиента как ключевое поле?


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
nullpoint
Дата 2.8.2014, 12:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 4.6.2013

Репутация: нет
Всего: нет



Цитата(feodorv @  2.8.2014,  12:07 Найти цитируемый пост)
Тогда при каждом обращении клиента для него будет сгенерирован новый ключ.

Нет. Ключ просто будет генерироваться независимо от того сколько раз клиент обратился. Новый ключ раз в сутки будет создаваться к примеру.


Цитата(feodorv @  2.8.2014,  12:07 Найти цитируемый пост)
незашифрованном виде уже не хорошо

Мне бы сначала просто отправить без шифрования:)


Цитата(feodorv @  2.8.2014,  12:07 Найти цитируемый пост)
Всё зависит от того, какую БД Вы хотите использовать.

MySQL


Можете показать как это реализовать без записи в БД? Т.е. сгенерировали ключ, отобразили его на экран в ASCII, приняли от клиента сообщение, посмотрели по базе идентификатор, отправили клиенту сообщение или вывели сообщение об ошибке, если нет такого идентификатора.
PM MAIL   Вверх
feodorv
Дата 6.8.2014, 22:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 10
Всего: 45



Цитата(nullpoint @  2.8.2014,  13:16 Найти цитируемый пост)
Можете показать как это реализовать без записи в БД? 

Гм. Я не работаю с QtCreator, поэтому тупые BSD сокеты. 


Цитата(nullpoint @  2.8.2014,  13:16 Найти цитируемый пост)
Т.е. сгенерировали ключ, отобразили его на экран в ASCII, приняли от клиента сообщение, посмотрели по базе идентификатор, отправили клиенту сообщение или вывели сообщение об ошибке, если нет такого идентификатора. 

Только сетевой обмен, остальное сами  smile 


Клиент
Код

#include <stdio.h>

#define PORT 20000

int readData( int socket, unsigned char *buf, int len)
{
  int length = 0, i;

  while( length < len )
  {
    int n = recv( socket, &buf[length], len-length, 0);
    if( n == 0 ) // соединение закрыто
    {
      printf( "  *** Connection closed by client\n" );
      return 0;
    }
    if( n < 0 ) // произошла ошибка
    {
      printf( "  *** Recv error\n" );
      return -1;
    }
    length += n;
  }

  printf( "  *** Got data(%d):", length);
  for( i = 0; i < length; i++)
    printf( "%s%02x", (i == 0) ? " " : ".", buf[i]);
  printf( "\n" );

  return length;
}

void doAction( int s )
{
  unsigned char query[5], message[15];

  query[0] = 0x45u;
  query[1] = 'A';
  query[2] = 'B';
  query[3] = 'C';
  query[4] = '\0';

  if( send( s, query, 5, 0) < 0 )
  {
    printf( "Can't send query\n" );
    return;
  }

  if( readData( s, message, 15) <= 0 ) return;

  printf( "OK\n" );
}

int client( void )
{
  struct sockaddr_in addr;
  int s;

  if( (s = socket( AF_INET, SOCK_STREAM, 0)) < 0 )
  {
    printf( "Can't open client socket\n" );
    return -1;
  }

  memset( &addr, '\0', sizeof(addr));
  addr.sin_family = AF_INET;
  addr.sin_addr.s_addr = htonl( INADDR_LOOPBACK );
  addr.sin_port = htons( PORT );
  if( connect( s, (struct sockaddr *) &addr, sizeof(addr)) < 0 )
  {
    printf( "Can't connect client socket\n" );
    close( s );
  }

  doAction( s );

  close( s );
  return 0;
}



Сервер
Код

#include <stdio.h>

#define PORT 20000

int readData( int socket, unsigned char *buf, int len)
{
  int length = 0, i;

  while( length < len )
  {
    int n = recv( socket, &buf[length], len-length, 0);
    if( n == 0 ) // соединение закрыто
    {
      printf( "  *** Connection closed by client\n" );
      return 0;
    }
    if( n < 0 ) // произошла ошибка
    {
      printf( "  *** Recv error\n" );
      return -1;
    }
    length += n;
  }

  printf( "  *** Got data:" );
  for( i = 0; i < length; i++)
    printf( "%s%02x", (i == 0) ? " " : ".",  buf[i]);
  printf( "\n" );

  return length;
}

void doAction( int s, struct sockaddr_in *sa)
{
  unsigned int ip = ntohl( sa->sin_addr.s_addr );
  unsigned int port = ntohs( sa->sin_port );
  unsigned char query[5];
  int len;

  printf( "Got connection from %.2u.%.2u.%.2u.%.2u:%u\n",
    (ip >> 24) & 0xffu, (ip >> 16) & 0xffu, (ip >> 8) & 0xffu, ip & 0xffu, port);

  if( (len = readData( s, query, 5)) <= 0 )
  {
    close( s );
    return;
  }

  if( query[4] != '\0' )
  {
    printf( "Invalid client data\n" );
    close( s );
    return;
  }

  printf( "  >>> Command = %x\n", query[0]);
  printf( "  >>> Client id = %s\n", &query[1]);

  if( query[0] == 0x45u )
  {
    unsigned char message[15];
    message[0] = 0x45u;
    message[1] = 0x42u;
    message[2] = query[1];
    message[3] = query[2];
    message[4] = query[3];
    message[5] = '\0';
    message[6] = 1;
    message[7] = 2;
    message[8] = 3;
    message[9] = 4;
    message[10] = 5;
    message[11] = 6;
    message[12] = 7;
    message[13] = 8;
    message[14] = 9;
    if( send( s, message, 15, 0) < 0 )
      printf( "  --- Error of send\n" );
    else
    {
      unsigned char data[1];
      shutdown( s, SD_SEND);
      // ждем подтверждения от клиента, что ответ принят
      if( readData( s, data, 1) < 0 )
      {
        // client error;
      }
    }
  }

  close( s );
}

int server( void )
{
  struct sockaddr_in addr;
  int ss;

  if( (ss = socket( AF_INET, SOCK_STREAM, 0)) < 0 )
  {
    printf( "Can't open server socket\n" );
    return -1;
  }

  memset( &addr, '\0', sizeof(addr));
  addr.sin_family = AF_INET;
  addr.sin_addr.s_addr = htonl( INADDR_ANY );
  addr.sin_port = htons( PORT );
  if( bind( ss, (struct sockaddr *) &addr, sizeof(addr)) < 0 )
  {
    printf( "Can't bind server socket\n" );
    close( ss );
    return -1;
  }

  if( listen( ss, 5) < 0 )
  {
    printf( "Can't listen server socket\n" );
    close( ss );
    return -1;
  }

  for( ;; )
  {
    int alen = sizeof(addr);
    int s = accept( ss, (struct sockaddr *) &addr, &alen);

    if( s < 0 )
    {
      printf( "Can't connect server socket\n" );
      close( ss );
      return -1;
    }

    doAction( s, &addr);
  }

  return 0;
}



--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
nullpoint
Дата 7.8.2014, 21:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 4.6.2013

Репутация: нет
Всего: нет



feodorv, спасибо, уже сам разобрался, но с помощью вашего кода подправил свое приложение smile
PM MAIL   Вверх
feodorv
Дата 7.8.2014, 21:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 10
Всего: 45



Цитата(nullpoint @  7.8.2014,  22:25 Найти цитируемый пост)
уже сам разобрался

 smile 


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Сети | Следующая тема »


 




[ Время генерации скрипта: 0.1930 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.