Помогите разобратся с сокет сервером на С++

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by malik555, 21 Jun 2009.

  1. malik555

    malik555 New Member

    Joined:
    4 Feb 2009
    Messages:
    132
    Likes Received:
    1
    Reputations:
    0
    Всем привет !

    Написал сокет сервер на с++ незнаю правельно или нет - но так работает и запросы принемает , проблема в том что я не как не могу ответить клиенту через функцию send() ,

    Code:
    
    int main ( )
    {
        int sockfd,client;
        sockfd = socket(PF_INET, SOCK_STREAM, 0);
        socklen_t n;
    
    
    struct sockaddr_in addr;
    bzero(&addr, sizeof(addr));
    
    addr.sin_family = AF_INET;
    addr.sin_port = htons(5190);
    addr.sin_addr.s_addr = htonl(INADDR_ANY);
    
    
    
    if(bind(sockfd,(struct sockaddr *) &addr, sizeof(addr)) != -1){
                
           cout << "SERVER - STARTED !!!" <<"\n";
                while(1) {
                          if(!listen(sockfd, 5)){
    
                               n = sizeof(addr);
                               if((client = accept(sockfd, (struct sockaddr *) &addr, &n)) != -1){
                               cout << "Coonect-" <<inet_ntoa(addr.sin_addr) <<"\n";
                                 
                                 char c;
                                 bool finished;
                                 char buffer[1024];
                                 finished = read(client, &c, 10);
                                 cout << client << "---" << c <<"\n";
    
                                 // вот сдесь и проблема не могу ответить клиенту !
                              int  hel;
                                   hel = "9999\0";
                                 send (client, hel, strlen(hel), 0);
                                 close(client);
                                 
                                 }
                             }
    
                }
     
     
     }
     else{cout << "NO SERVER" << "\n";}
    
    
      
    }
    
     
  2. razb

    razb Active Member

    Joined:
    24 Mar 2009
    Messages:
    658
    Likes Received:
    133
    Reputations:
    18
    Во первых listen() запускается только один раз, во вторых внимательно пересмотри этот участок кода
    Code:
                                 char c;
                                 bool finished;
                                 char buffer[1024];
                                 finished = read(client, &c, 10);
                                 cout << client << "---" << c <<"\n";
    
                                 // вот сдесь и проблема не могу ответить клиенту !
                              int  hel;
                                   hel = "9999\0";
                                 send (client, hel, strlen(hel), 0);
                                 close(client);
    
    Внимательно прочитай документацию по сетевым ф-циям!
     
  3. --StraNger--

    --StraNger-- Member

    Joined:
    4 Jan 2009
    Messages:
    63
    Likes Received:
    57
    Reputations:
    5
    стоит попробовать объявить переменную hel как char
     
  4. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,702
    Likes Received:
    1,224
    Reputations:
    455
    close -> closesocket
    read -> recv
    hel - у тя int сделать хотябы char hel[размер]
    strlen - тока для строк работает

    у тебя наверное при компиле сотни варнингов на экран вылетают
     
  5. malik555

    malik555 New Member

    Joined:
    4 Feb 2009
    Messages:
    132
    Likes Received:
    1
    Reputations:
    0
    Вобщем разобрался с отправкой ответа , скрипт немного переделал

    Code:
    int main ( )
    {
        int sockfd,client;
            sockfd = socket(PF_INET, SOCK_STREAM, 0);
            socklen_t size;
     struct sockaddr_in addr;
     bzero(&addr, sizeof(addr));
    
            addr.sin_family = AF_INET;
            addr.sin_port = htons(PORT);
            addr.sin_addr.s_addr = htonl(INADDR_ANY);
    
              // bind()
            if(bind(sockfd,(struct sockaddr *) &addr, sizeof(addr)) != 0){
                    cout << "Error - bind() !" << "\n"; 
                    return 0;
                    }
              // listen()
            if(listen(sockfd, 5) != 0){
                    cout << "Error - listen() !" << "\n";
                    return 0;
                    }
                     
                    
                    while(1) {
                                 size = sizeof(addr);
                                 client = accept(sockfd, (struct sockaddr *) &addr, &size);
    
                                 if(client > 0){
    
                                        cout << "Coonect-" <<inet_ntoa(addr.sin_addr) <<"\n";
    
                                        // - пришли данные
                                   char buffer[1024];
                                        bzero(buffer,sizeof(buffer));
                                        recv(client, buffer, sizeof(buffer),0);
                                        cout << buffer << "\n";
    
                                        //- ответ клиенту
                                   char *reply = "ggg";
                                   send(client, reply, strlen(reply)+1, 0);
    
                                 }
                    }  
    }
    
    
    Получается к серверу конектятся клиенты и обмениваются данными - конект поддерживается постоянно с клиентом - и вот проблема как определить на стороне сервера что клиент

    отключился - разорвал соеденение ?
     
  6. malik555

    malik555 New Member

    Joined:
    4 Feb 2009
    Messages:
    132
    Likes Received:
    1
    Reputations:
    0
    Или подскажите куда капать - по поваду (как определить на стороне сервера что клиент отключился - разорвал соеденение ?)
     
  7. --StraNger--

    --StraNger-- Member

    Joined:
    4 Jan 2009
    Messages:
    63
    Likes Received:
    57
    Reputations:
    5
    Попробуй использовать WSAEventSelect
    это события
     
  8. malik555

    malik555 New Member

    Joined:
    4 Feb 2009
    Messages:
    132
    Likes Received:
    1
    Reputations:
    0
    Да что-то не получается с этим - на perl это все решается очень просто - на c++ еще не найду сдравого решения !
     
  9. malik555

    malik555 New Member

    Joined:
    4 Feb 2009
    Messages:
    132
    Likes Received:
    1
    Reputations:
    0
    Вобщем написал сокет сервер - все работает только выдает 2 warning: при компиляции , я не могу их устранить

    вот полный код сервера

    Code:
    
    #include <iostream.h>
    #include <sys/socket.h>
    #include <sys/types.h>
    #include <netinet/in.h>
    #include <time.h>
    #include <arpa/inet.h>
    
    
    
    #define PORT  5190
    #define SERVER_IP "000.000.00.000"
    
    
               
    
    
    
    
    void NewClient (int client){
    
    
        while(1){
    
           char buffer[1024];
                bzero(buffer,sizeof(buffer));
                if(recv(client, buffer, sizeof(buffer),0) != 0){
    
                                 cout << buffer "\n";      
                        
                  }
    
           }
    
    }
    
    
    
    
    
    int main ( )
    {
        int sockfd,client;
            sockfd = socket(PF_INET, SOCK_STREAM, 0);
            socklen_t size;
     struct sockaddr_in addr;
     bzero(&addr, sizeof(addr));
    
            addr.sin_family = AF_INET;
            addr.sin_port = htons(PORT);
            addr.sin_addr.s_addr = htonl(INADDR_ANY);
    
              // bind()
            if(bind(sockfd,(struct sockaddr *) &addr, sizeof(addr)) != 0){
                    cout << "Error - bind() !" << "\n"; 
                    return 0;
                    }
              // listen()
            if(listen(sockfd, 5) != 0){
                    cout << "Error - listen() !" << "\n";
                    return 0;
                    }
                     
                    
                    while(1) {
                                 size = sizeof(addr);
                                 client = accept(sockfd, (struct sockaddr *) &addr, &size);
    
                                 if(client > 0){
    
                                                 cout << "Coonect-" <<inet_ntoa(addr.sin_addr) <<"\n";
    
                                                 char buffer[1024];
                                                      bzero(buffer,sizeof(buffer));
                                                      recv(client, buffer, sizeof(buffer),0);
                                                   if(buffer == "<policy-file-request/>"){
                                                      char *mes = "<?xml version='1.0'?><cross-domain-policy><allow-access-from domain='*' to-ports='*' /></cross-domain-policy>";
                                                      send(client, mes, strlen(mes)+1, 0);
                                                      close(client);
                                                      return 1;
                                                    }
    
                                                 if(!fork()){
    
                                                    NewClient(client);
    
                                             }
         
    
                                 }
    
    
                    }
    
    
                      
    }
    
    
    а вот предупреждение при компиляции

    In file included from /usr/include/c++/4.2/backward/iostream.h:31,
    from server.cpp:1:
    /usr/include/c++/4.2/backward/backward_warning.h:32:2: warning: #warning This file includes at least one deprecated or antiquated header. Please consider using one of the 32 headers found in section 17.4.1.2 of the C++ standard. Examples include substituting the <X> header for the <X.h> header for C++ includes, or <iostream> instead of the deprecated header <iostream.h>. To disable this warning use -Wno-deprecated.
    server.cpp: In function 'int main()':
    server.cpp:107: warning: deprecated conversion from string constant to 'char*'

    по <iostream.h> пытался так <iostream>
    тогда вобще ошибок море все на cout указывают .

    а 'char*' тоже незнаю как устранить !

    Подскажите пожалуйста !
     
  10. razb

    razb Active Member

    Joined:
    24 Mar 2009
    Messages:
    658
    Likes Received:
    133
    Reputations:
    18
    При использовании <iostream> все обьекты библиотеки находятся в пространстве std, для этого необходимо либо в начале написать using namespace std; либо явно указывать пространство имен, например так std::cout

    Далее эту запись замени
    Code:
    char *mes = "<?xml version='1.0'?><cross-domain-policy><allow-access-from domain='*' to-ports='*' /></cross-domain-policy>";
    на вот эту
    Code:
    char mes[] = "<?xml version='1.0'?><cross-domain-policy><allow-access-from domain='*' to-ports='*' /></cross-domain-policy>";
    П.С. в следующий раз пиши конкретно в какой строке ошибки/предупреждения, а то тут у тебя написано в 107, а кода меньше чем на 100 строк.
     
    #10 razb, 30 Jun 2009
    Last edited: 30 Jun 2009
  11. malik555

    malik555 New Member

    Joined:
    4 Feb 2009
    Messages:
    132
    Likes Received:
    1
    Reputations:
    0
    Спасибо !

    Это я ступил , я компилил когда полный файл был а на форум выложил - лишнее удалил что-б меньше кода было - оставил главное !
     
  12. malik555

    malik555 New Member

    Joined:
    4 Feb 2009
    Messages:
    132
    Likes Received:
    1
    Reputations:
    0
    Собственно возник еще один вопрос по сокетам


    весь код вылаживать не буду приведу часть



    Code:
    
      // когда подключается новый клиент я создаю новый
     // процес
    
           if(!fork()){
               
               // и посылаю его в функцию  NewClient()  
               NewClient(client);
    
           }
            
    
           void NewClient (int client){
    
                   
                    while(1){  // бесконечный цыкл
    
    
                        // принимаю сообщение от клиента       
                       char buffer[1024];          
                       bzero(buffer,sizeof(buffer));
                       recv(client, buffer, sizeof(buffer),0);
                       if(strlen(buffer) > 0){
                         
                            cout << buffer ;
    
                          }
    
                        /* вопрос !  Почему этот цыкл while  
                            выполняется только когда приходит
                            сообщение от клиента - если нет 
                            сообщений то и цыкл не выполняется
                            по идеии он должен выполнятся 
                            постоянно ?
                         */
                         
                  }
    
    
    
    
          }
    
    
     
    #12 malik555, 3 Jul 2009
    Last edited: 3 Jul 2009
  13. razb

    razb Active Member

    Joined:
    24 Mar 2009
    Messages:
    658
    Likes Received:
    133
    Reputations:
    18
    У тебя блокируемые сокеты, это означает что когда выполнение цикла доходит до recv(client, buffer, sizeof(buffer),0); далее ожидается прием данных от клиента, как только они пришли выполнение продолжается.
     
  14. malik555

    malik555 New Member

    Joined:
    4 Feb 2009
    Messages:
    132
    Likes Received:
    1
    Reputations:
    0

    Это вобще правельно так ? и можно сделать что-б цыкл постоянно крутился ?