На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
  
    > алгоритм работы простого сервера
      Опишите кто-нибудь сабж. И если можно, примерчик для изучения на C киньте, только без MFC. Протокол  TCP желательно.
        Простой сервер TCP достаточно прост :)

        Значит так...

        Прежде всего перед тем как начать работать с сокетами (winsock) надо их инициализировать. Это делается так:

        ExpandedWrap disabled
          <br>WSADATA WSAData;<br>if(WSAStartup(0x0101,&WSAData)){<br>      //Ошибка<br>}<br>


        Певрый параметр это версия сокетов, а второй буфер в которой при успешной инициализации вернётся структура WSADATA.

        Теперь, когда сокеты инициалезированны, можем приступить к следующему шагу - созданию сокета:

        ExpandedWrap disabled
          <br>SOCKET s = socket(AF_INET, SOCK_STREAM,0);<br>


        Ну а сокет он как и любой сокет имеет ряд свойств, типа протикола, порта, интерфейса и т.д. В принципе при создании сокета уже устанавиваются значения по умолчанию, но мы к нему тем не менее привязуем порт и интервейс с которым он будет работать:

        ExpandedWrap disabled
          <br>sockaddr_in addr;<br>addr.sin_family = AF_INET;      //Семейство протоколов<br>addr.sin_port = htons(7722);      //Порт<br>addr.sin_addr.s_addr=inet_addr("192.168.100.11");      //Интерфейс<br>if(bind(s,(LPSOCKADDR)&addr,sizeof(addr)) == SOCKET_ERROR)<br>{<br>      //Ошибка вызова вункции bind()<br>}<br>


        Мы можем впринципе выбрать любой свободный порт, а можем поручить выбор порта выню, установив значение sin_port равным 0.
        Функция htons() нам нужна для того чтобы при заполнении структуры числа запсывать в сетевом порядке, т.е. в процах семейства intel числа записываются так: по младшему адресу лежит млачший разряд, а в сетевом порядке всё так-же но в точности наоборот :)
        Функция inet_addr() переводит строку с IP адрессом интерфейса в его двоичное значение (DWORD), если для нас нет необходимости привязывать сокет к конкретному интерфейсу, то мы заполняем этот член структуры значением INADDR_ANY

        Чтобы получить IP адреса нашего хоста есть несколько полезных функций:

        ExpandedWrap disabled
          <br>char hostname [100];<br>gethostname(hostname,sizeof(hostname)); // Получить имя хоста<br>


        и

        ExpandedWrap disabled
          <br>gethostbyname(hostname); // Получить указатель на структуру<br>


        (подробней о структуре хоста поищи в МСДНе или если не найдёш спрашивай (я на память не помню))

        Теперь, можно уже сказать, что сервер почти готов, осталась пара пустяков...

        Так как мы создаём ни что-то там, а сервер, то к нему должны будут подсоединяться клиенты, а значит нам надо создать очередь для соединяющихся клиентов:

        ExpandedWrap disabled
          <br>if(listen(s,5) == SOCKET_ERROR)<br>{<br>      //Ошибка вызова вункции listen()<br>}<br>


        Ну вот... теперь может находиться в ожидании своей очереди до 5 клиентов.
        Теперь надо получить из очереди подсоединившегося клиента, чтобы его обслужить:

        ExpandedWrap disabled
          <br>int nAddrLen=sizeof(sockaddr);<br>sockaddr Ot;<br>SOCKET In;<br>In=accept(s,&Ot,&nAddrLen);<br>


        функция accept() возвращает сокет для работы с клиентом
        Уже можно начинать сианс связи по установленному протоколу.
        Т.е. Для нормальной работы сервера и клиента должен быть отработан определённый протокол.
        Предположим, что наш эхосервер сначала должен получить строку от клиента, а потом отослать ему ответ и закрыть соединение.

        Значит это будет выглядеть так:

        ExpandedWrap disabled
          <br>int nLen;            //Размер полученных/переданных данных<br>char buf[1000];<br><br>nLen=recv(In,buf,1000,0);<br>if(nLen==0){<br>      //Клиент закрыл соединение<br>}<br>else if(nLen<0){<br>      //Произошла ошибка<br>}<br>esle{<br>      //Всё нормально, данные получены!<br>      //Отослать ответ<br>      nLen=send(In,buf,nLen,0);<br>}<br><br>shutdown(In,2);<br>closesocket(In);<br>



        Вот в общем тот минмум, который должен помочь в этом деле :)

        Пример простенького сервера посмотри в этом топе:
        http://pascal.sources.ru/cgi-bin/forum/YaBB.cgi?board=cpp;action=display;num=1049898059

        Будут вопросы, задавай...


        P.S. Да!! И чуть не забыл, для работы с winsock надо подключить вот этот заголовок #include <winsock.h>
        Сообщение отредактировано: old_lamer -
          Спасибо, почти разобрался.

          >>Пример простенького сервера посмотри в этом топе:
          >>http://pascal.sources.ru/cgi-bin/forum/YaBB.cgi?board=cpp;action=display ;num=1049898059
          только работает он криво :)
          0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
          0 пользователей:


          Рейтинг@Mail.ru
          [ Script execution time: 0,7386 ]   [ 16 queries used ]   [ Generated: 13.12.24, 00:19 GMT ]