На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
  
    > Работа с WinSocket's , Клиент-сервер через порт
      Товарищи!
      Позарез нужно срочно написать нечто в духе Telnet.
      Подскажите как это делать?

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

      КАК ЭТО СОТВОРИТЬ? ГДЕ ПРО ЭТО ПОЧИТАТЬ?

      Может кто-нибудь исходники накидать, чтобы разобраться?

      Видел в одном месте кое-что но там это под Linux, а мне надо под Винды.


      Может кто шарит, скажите как доработать это:
      ExpandedWrap disabled
        #include "stdafx.h"
        #include <stdio.h>
        #include <conio.h>
        #include <winsock2.h>
        #include <protocol.h>
         
        #define MAX_PACKET_SIZE  0x10000
        #define SIO_RCVALL 0x98000001
         
        static char Buffer[MAX_PACKET_SIZE];
         
        int main(int argc, char* argv[])
        {
            WSADATA       wsadata;   // Инициализация WinSock.
            SOCKET        s;         // Cлущающий сокет.
            char          name[128]; // Имя хоста (компьютера).
            HOSTENT*      phe;       // Информация о хосте.
            SOCKADDR_IN   sa;        // Адрес хоста
            unsigned long flag = 1;  // Флаг PROMISC Вкл/выкл.
         
            // инициализация
            WSAStartup(MAKEWORD(2,2), &wsadata);
            s = socket( AF_INET, SOCK_RAW, IPPROTO_IP );
            gethostname(name, sizeof(name));
            phe = gethostbyname( name );
            ZeroMemory( &sa, sizeof(sa) );
            sa.sin_family = AF_INET;
            sa.sin_addr.s_addr = ((struct in_addr *)phe->h_addr_list[0])->s_addr;
            bind(s, (SOCKADDR *)&sa, sizeof(SOCKADDR));
         
            // Включение promiscuous mode.
            ioctlsocket(s, SIO_RCVALL, &flag);
            long cnt = 0;
            // Приём IP-пакетов.
            while( !_kbhit() )
                {
                    int count;
                    printf("%d", cnt++);
                    count = recv( s, Buffer, sizeof(Buffer), 0 );
                    // обработка IP-пакета
                    if( count >= sizeof(IP_HEADER) )
                        {
                            IP_HEADER* hdr = (IP_HEADER *)Buffer;
                            //что-то делаем с пакетом...
                        }
                }
            // Конец работы.
            closesocket( s );
            WSACleanup();
            return 0;
        }

      Как привести этот сервер в нужный вид и дописать к нему клиент
      Сообщение отредактировано: ViGOur -
        А нужно чтоб много клиентов могли к серверу подключится одновременно???

        Добавлено
        Если да то вот так можно:

        Server :
        ExpandedWrap disabled
          #include <stdio.h>
          #include <string.h>
          #include <winsock2.h>
          #include <conio.h>
           
          #pragma comment(lib, "ws2_32.lib")
           
          #define PORT 31337
           
          SOCKADDR_IN socketaddr;
          SOCKET sock;
          const int WM_SERVER_ACCEPT = WM_USER+1;
           
          int nclients = 0;
           
          DWORD WINAPI SexToClient(LPVOID client_socket);
          bool _startserver();
          HWND GetConsoleHWND();
           
           
          int main()
          {
              _startserver();
              return 0;
          }
           
           
           
          bool _startserver()
          {
           
          WSADATA wsaData;
           
          if (WSAStartup(MAKEWORD(2,2), &wsaData))
          {
              printf ("Winsock not bi initialized !\n");
              WSACleanup();
              return false;
          }
           
           
          if ((sock=socket(AF_INET,SOCK_STREAM,0))<0)
          {
          printf("Error socket %d\n",WSAGetLastError());
          WSACleanup();
          return false;
          }
           
           
          sockaddr_in local_addr;
          local_addr.sin_family=AF_INET;
          local_addr.sin_port=htons(31337);
          local_addr.sin_addr.s_addr=INADDR_ANY;
           
           
          if (bind(sock,(struct sockaddr *)&local_addr,sizeof(local_addr))==SOCKET_ERROR)
          {
           
          printf("Error bind %d\n",WSAGetLastError());
          closesocket(sock);
          WSACleanup();
          return false;
          }
           
          if (listen(sock, 0x100))
          {
           
          printf("Error listen %d\n",WSAGetLastError());
          closesocket(sock);
          WSACleanup();
          return false;
          }
           
          printf("Waiting for connections...\n");
           
          int len=sizeof(local_addr);
           
          SOCKET client_socket; // сокет для клиента
          sockaddr_in client_addr; // адрес клиента (заполняется системой)
           
          int client_addr_size=sizeof(client_addr);
           
          while((client_socket=accept(sock, (sockaddr *)&client_addr, &client_addr_size)))
          {
          nclients++; // увеличиваем счетчик подключившихся клиентов
           
          // пытаемся получить имя хоста
          HOSTENT *hst;
          hst=gethostbyaddr((char *)&client_addr.sin_addr.s_addr,4,AF_INET);
           
          // вывод сведений о клиенте
          printf("+%s [%s] new connect!\n",
          (hst)?hst->h_name:"",inet_ntoa(client_addr.sin_addr));
          printf("NEWS USER\n");
          //printf("ncl inf: = %l",client_socket[nclients]);
                
          ////////////////////////////////////////////////
          ////////////////////////////////////////////////
          // Вызов нового потока для обслужвания клиента
          // Да, для этого рекомендуется использовать _beginthreadex
          // но, поскольку никаких вызов функций стандартной Си библиотеки
          // поток не делает, можно обойтись и CreateThread
          DWORD thID;
          CreateThread(NULL,NULL,SexToClient,&client_socket,NULL,&thID);
          ///////////////////////////////////////////////
          ///////////////////////////////////////////////
           
          }
           
          return true;
           
          }
           
           
          HWND GetConsoleHWND()
          {
              SetConsoleTitle("Sarver started...");
              HWND hwndConsoleWindow;
              hwndConsoleWindow=FindWindow(NULL, "Sarver started...");
              if (hwndConsoleWindow==0)
              {
                  printf("Error Find Window");
                  exit(0);
              }
              return hwndConsoleWindow;
          }
           
          // Эта функция создается в отдельном потоке
          // и обсуживает очередного подключившегося клиента независимо от остальных
           
          DWORD WINAPI SexToClient(LPVOID client_socket)
          {
           
          SOCKET my_sock;
          my_sock=((SOCKET *) client_socket)[0];
          char buff[9999];
          #define sHELLO "Hello, Sailor\r\n"
           
          // отправляем клиенту приветствие
          send(my_sock,sHELLO,sizeof(sHELLO),0);
           
          // цикл эхо-сервера: прием строки от клиента и возвращение ее клиенту
          while(int recvbyte = recv(my_sock,buff,sizeof(buff),0))
          {
              //главный цикл обработки сообщений от клиентов...
              if(recvbyte<=0)
              {
                  break;
              }
              printf("Client=> %s",buff);
              send(my_sock,buff,strlen(buff),0);
              buff[0]=0;
          }
          // если мы здесь, то произошел выход из цикла по причине
          // возращения функцией recv ошибки – соединение с клиентом разорвано
          nclients--; // уменьшаем счетчик активных клиентов
          printf("-disconnect\n");
           
          // закрываем сокет
          closesocket(my_sock);
           
          return 0;
          }


        Client
        ExpandedWrap disabled
          #include <stdio.h>
          #include <string.h>
          #include <winsock2.h>
           
          #pragma comment(lib, "ws2_32.lib")
           
          #define PORT 31337
          char* HOST="127.0.0.1";
           
          SOCKADDR_IN socketaddr;
          SOCKET sock;
           
           
          bool _connect(char* addres);
          bool _getdata();
           
          int main(int argc, char* pszArgs[])
          {
              
              if(argc>1)
              {
                  HOST=pszArgs[1];        
              }
           
              if(_connect(HOST))
                  _getdata();
           
              scanf("A");
           
              return 0;
          }
           
           
           
          bool _connect(char* addres)
          {
              WSADATA wsaData;
           
              if (WSAStartup(MAKEWORD(2,2), &wsaData))
              {
                  printf ("Winsock not bi initialized !\n");
                  WSACleanup();
                  return false;
              }
              
              sock = socket(AF_INET,SOCK_STREAM,0);
           
              socketaddr.sin_family = AF_INET;
              socketaddr.sin_addr.s_addr=inet_addr(addres);
              socketaddr.sin_port=htons(PORT);
              
              if(connect(sock,(sockaddr *)&socketaddr,sizeof(socketaddr)))
              {
                  printf("Can\'t connect to %s\n\n",addres);
                  WSACleanup();
                  return false;
              }
              else
                  printf("Connected!\n\n\n\n");
           
              return true;
          }
           
           
           
           
          bool _getdata()
          {
          char buff[1024];
          int nsize;
          while((nsize=recv(sock,buff,sizeof(buff),0))!=SOCKET_ERROR)
          {
          // ставим завершающий ноль в конце строки
          //buff[nsize]=0;
           
          // выводим на экран
              buff[nsize]='\0';
          printf("Server =>  %s\n",buff);
           
           
          // читаем пользовательский ввод с клавиатуры
          printf("=> ");
          fgets(buff,sizeof(buff),stdin);
           
          // проверка на "quit"
          if (!strcmp(&buff[0],"quit\n"))
          {
          // Корректный выход
          printf("Exit...");
          closesocket(sock);
          WSACleanup();
          return true;
          }
           
          //шлем дату...
          send(sock,buff,sizeof(buff),0);
           
          }
           
          return true;
           
          }


        Сервер слушает порт 31337 на подключение клиентов...
        Сообщение отредактировано: Jenizix -
          Спасибо.
          А если клиент может подрубаться только один? Какой кусок кода измениться?
            2 YOG:
            тот код, что ты привел - это код сниффера(программа которая перехватывает пакеты), в твоем случае она будет перехватывать весь трафик...доработать не получится, надо переделывать полностью...
              Цитата
              А если клиент может подрубаться только один? Какой кусок кода измениться?

              У меня нет, сколько хочешь....

              Добавлено
              Ну а так подключение нового клиента обрабатывает ф-ия accept
              Сообщение отредактировано: Jenizix -
                M
                YOG, Используем тег [code] для добавления текста программы в пост! Устное предупреждение! Читаем правила!

                Jenizix, если слишком длинный код, то лучше выкладывать исходник, а не постить в теге [CODE].  ;)
                  ExpandedWrap disabled
                    send(my_sock,sHELLO,sizeof(sHELLO),0);
                    // Тут конечно можно написать третьим параметром sizeof(sHELLO)
                    // т.к. #define sHELLO "Hello, Sailor\r\n"
                     
                    send(sock,buff,sizeof(buff),0);
                    // А вот тут советую поменять sizeof() на strlen() ибо char buff[9999];
                  Сообщение отредактировано: MOHAX -
                    Может у кого нить есть сервер и клиент не в консольном варианте, а в диалоговом (хотябы :))с примитивным набором функций. Нормально произвести коннект, и возможность отправлять мессаги типа - HelloWorld :D в обе стороны ессесно.
                    Если есть, то уже очень хотелось бы посмотреть на него!
                    Сообщение отредактировано: madman -
                    0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                    0 пользователей:


                    Рейтинг@Mail.ru
                    [ Script execution time: 0,0330 ]   [ 16 queries used ]   [ Generated: 18.04.24, 15:47 GMT ]