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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Обработка комманд, полученных через сокеты 
:(
    Опции темы
Chupik
Дата 5.4.2009, 21:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Собственно, этот вопрос был в одном сабже ветки "Для новичков", но мне посоветовали обратится сюда. smile 

Итак, пишу что-то вроде небольшого бота для дистанционного управления компьютером.

Вот его клиентская часть:

Код

#pragma comment( lib, "wsock32.lib" )
#include<stdio.h>
#include<iostream>
#include<winsock2.h>
using namespace std;
void main()
{
    WORD wVersionRequested;
    WSADATA wsaData;
    int err;
    wVersionRequested = MAKEWORD( 2, 2 );
    err=WSAStartup( wVersionRequested, &wsaData );
    if ( err != 0 ){return;}
while (true)
{
    SOCKET s=socket(AF_INET,SOCK_STREAM,0);
    sockaddr_in dest_addr;
    dest_addr.sin_family=AF_INET;
    dest_addr.sin_port=htons(1280);
    dest_addr.sin_addr.s_addr=inet_addr("127.0.0.1");
    connect(s,(sockaddr *)&dest_addr,sizeof(dest_addr));
    
    char buf[100];
    char pol[100];
    cout<<"Enter the string:"<<endl;
    fgets(buf,sizeof(buf),stdin);
    send(s,buf,100,0);
    if (recv(s,pol,sizeof(buf),0)!=0)
    {
        cout<<"Received string:"<<endl<<pol<<endl;
    }
    closesocket(s);
}
WSACleanup();
}


Вот серверная:

Код

#pragma comment( lib, "ws2_32.lib" )
#include <iostream>
#include <string>
#include <windows.h>
using namespace std;
DWORD WINAPI ThreadFunc(LPVOID client_socket)
{
    SOCKET s2=((SOCKET *) client_socket)[0];
    char buf[100];
    char res[100], *z;
     strcpy(res, "");     
     std::string receive_string;
    while(recv(s2,buf,sizeof(buf),0))
    {
        receive_string = buf;
        int n=0,k=0;
        k=strlen(buf)-1;
        if (k>=2)
        {
            z=buf;
            sscanf(z+=n," %s%n",res, &n);
            cout<< "Buf. value:" << buf <<endl;
            send(s2,res,100,0);
        }
        else if ( receive_string == "/still_alive" ) {
        send(s2,"Hello, world! Test.",100,0);
    }
        else
            send(s2,"The string lenght is less than 2 symbols",100,0);
    }
    closesocket(s2);
    return 0;
}
int numcl=0;
//************************************************************
void print()
{
    if (numcl) printf("%d client connected\n",numcl);
    else printf("No clients connected\n");
}
//************************************************************
void main()
{
    WORD wVersionRequested;
    WSADATA wsaData;
    int err;
    wVersionRequested = MAKEWORD( 2, 2 );
    err = WSAStartup( wVersionRequested, &wsaData );
    if ( err != 0 ){return;}
    SOCKET s=socket(AF_INET,SOCK_STREAM,0);
    sockaddr_in local_addr;
    local_addr.sin_family=AF_INET;
    local_addr.sin_port=htons(1280);
    local_addr.sin_addr.s_addr=0;
    bind(s,(sockaddr *) &local_addr,sizeof(local_addr));
    int c=listen(s,5);
    cout<<"Server receive ready"<<endl;
        SOCKET client_socket;    
    sockaddr_in client_addr;
    int client_addr_size=sizeof(client_addr);
    while((client_socket=accept(s,(sockaddr *)&client_addr, &client_addr_size)))
    {
      numcl++;   
      print();
            DWORD thID;// thID идентификатор типа DWORD
      CreateThread(NULL,NULL,ThreadFunc,&client_socket,NULL,&thID);
    }
    
}


Проблема в том, что сервер никак не распознаёт команду:

 
Код

else if ( receive_string == "/still_alive" ) {
        send(s2,"Hello, world! Test.",100,0); }


т.е. когда я отправляю /still_alive он мне возращает не Hello, world! Test, а как обычно мою посланную команду(/still_alive).

В чём загвоздка? 

Заранее огромное спасибо. smile 

P.S. Поиск по сайту уже использовал... Гугл тоже.

Это сообщение отредактировал(а) Chupik - 5.4.2009, 21:49
PM MAIL   Вверх
Irdis
Дата 6.4.2009, 00:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Код

 char buf[100];
k=strlen(buf)-1;
        if (k>=2)


99>=2 я бы с этим спорить не стал,


Это сообщение отредактировал(а) Irdis - 6.4.2009, 00:59
PM MAIL   Вверх
vinick
Дата 6.4.2009, 10:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



TCP - потоковый протокол, нет никаких гарантий, что за один вызов recv ты получишь ровно одно сообщение. Нужен внутренний  накопительный буфер.

Добавлено через 10 минут и 17 секунд
Код

    cout<<"Enter the string:"<<endl;
    fgets(buf,sizeof(buf),stdin);
    send(s,buf,100,0);


Ты читаешь строку, например в 10 байт, а на сервер отсылаешь 100.  Сервер получает лишний мусор.
И еще, пройдись отладчиком по серверу, посмотри чему у тебя равен receive_string. Возможно туда этот мусор и попадает.

Это сообщение отредактировал(а) vinick - 6.4.2009, 10:58
PM MAIL ICQ Jabber   Вверх
Chupik
  Дата 6.4.2009, 12:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Irdis, vinick, большое спасибо, сейчас прогоню в отладчике. 
PM MAIL   Вверх
Chupik
  Дата 6.4.2009, 12:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Итак, результаты прогона на отладчике:
Поток: buf
Значение: ¬.6
Поток: receive_string 
Значение: {}

Поток: buf
Значение: tfgf (как раз то, которое я ввёл в клиенте)
Поток: receive_string
Значение: {""}.

Вот так вот, что-то со  receive_string непонятное...


Добавлено позже:

Решил по другому немного попробовать:

 
Код

else if ( strcmp(buf, "/test" ) == 0 ) {
        send(s2,"Hello, world! Test.",100,0);
        cout << "Test test test i td" << endl;
    }


тоже не срабатывает...

Добавленно позже:

А вот результаты последнего прогона:

значение buf  "still_alive"
значение receive_string  {"still_alive"}

Это сообщение отредактировал(а) Chupik - 6.4.2009, 14:07
PM MAIL   Вверх
Chupik
  Дата 8.4.2009, 19:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Up... smile 

Итак я понял, что кажись простым конвертированием из char * в string или int ничего не получится...

 
Код

std::string receive_string;
 receive_string = buf;


receive_string получается тоже массивом(слово test выглядит [1] = t; [2] = e; [3] = s и т.д...) и при сравнении:

Код

else if (receive_string == "/test") {
        send(s2,"Hello, world! Test.",100,0);
        cout << "GlaDOS mod on..." << endl;
    }


или:

Код

char buf[100];
char ppc[100] = "/test";
.....
else if (buf == ppc) {
        send(s2,"Hello, world! Test.",100,0);
        cout << "GlaDOS mod on..." << endl;
    }


ноль эмоций... smile 


P.S. Сори за 3 пост подряд...

Это сообщение отредактировал(а) Chupik - 8.4.2009, 20:02
PM MAIL   Вверх
jonie
Дата 8.4.2009, 20:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



конечно, тыже сравниваешь значения указателей, а не сами данные. Используй memcmp или для строк strcmp функции.


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
Chupik
Дата 8.4.2009, 20:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(jonie @  8.4.2009,  20:18 Найти цитируемый пост)
Используй memcmp


Код

char buf[100];
char ppc[100] = "/test";
int result;
result=memcmp(buf,ppc,100);
****
else if (result = 0) 
****


Тоже самое.. Пишу /test - реагирует по прежнему...

Цитата(jonie @  8.4.2009,  20:18 Найти цитируемый пост)
strcmp функции. 


Уже использовал, на два поста выше:

Код

else if ( strcmp(buf, "/test" ) == 0 )


тоже не работает smile 

PM MAIL   Вверх
vinick
Дата 8.4.2009, 20:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(Chupik @  5.4.2009,  21:46 Найти цитируемый пост)
 
k=strlen(buf)-1;
        if (k>=2)
        {
            z=buf;
            sscanf(z+=n," %s%n",res, &n);
            cout<< "Buf. value:" << buf <<endl;
            send(s2,res,100,0);
        }
        else if ( receive_string == "/still_alive" ) {
        send(s2,"Hello, world! Test.",100,0);


Пример:
buf == "/still_alive"
k = strlen(buf)-1 == 11;
Выполняется условие k>=2 и под else просто никогда не войдет.

И не пихай размер в 100 байт во все функции.
PM MAIL ICQ Jabber   Вверх
Chupik
Дата 8.4.2009, 21:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Спасибо smile Пофиксил, сделал так:
Код

...................
   char buf[10];
    char res[10], *z;
     strcpy(res, "");     
     std::string receive_string;
    while(recv(s2,buf,sizeof(buf),0))
    {
        receive_string = buf;
        int n=0,k=0;
        
         if ( strcmp(buf, "/test" ) == 0 ) {
        send(s2,"Hello, world! Test.",10,0);
        cout << "GlaDOS mod on..." << endl;
    }
         else {
            z=buf;
            sscanf(z+=n," %s%n",res, &n);
            cout<< "Buf. value:" << buf <<endl;
            send(s2,res,10,0);   }
    }
    closesocket(s2);
    return 0;
................

т.е. размеры буферов уменьшил, убрал проверку на наличие символов, но... на команду /test не отзывается как надо...  smile 

З.Ы. Простите, что задаю много глупых вопросов. smile 
PM MAIL   Вверх
vinick
Дата 8.4.2009, 22:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(Chupik @  8.4.2009,  21:32 Найти цитируемый пост)
на команду /test не отзывается как надо... 

у тебя в клиенте fgets читает кроме строки "/test" еще и символ перевода строки и дописывает его в buf, который ты отправляешь на сервер.

На сервере у тебя в buf на самом деле лежит "/test\r\n\0" или "/test\n\0", поэтому strcmp(buf,"/test") не работает как ожидалось.


Цитата(Chupik @  8.4.2009,  21:32 Найти цитируемый пост)
размеры буферов уменьшил, 

Я не говорил, что размеры буферов надо уменьшать, я имел ввиду что надо писать реальные размеры строк, а не 100 байт во всех функциях указывать. Теперь у тебя вобще бардак с памятью.

Вместо 
Код

 send(s2,"Hello, world! Test.",10,0); /// <- !!!!
 ...
 send(s2,res,10,0);  


надо 
Код

send(s2,"Hello, world! Test.",20,0); 
 ...
 send(s2,res,strlen(res)+1,0);  

и в других местах так же.
PM MAIL ICQ Jabber   Вверх
Chupik
  Дата 19.4.2009, 21:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



vinick, спасибо, понял свои ошибки. smile 


PM MAIL   Вверх
J0ker
Дата 22.4.2009, 00:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



писание програм методом тыка никогда и ни у кого не получалось


--------------------
user posted image
PM MAIL   Вверх
GrayCardinal
Дата 23.4.2009, 09:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Фигасе
****


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

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



Цитата

писание програм методом тыка никогда и ни у кого не получалось 

Не скажите... Метод самое то...  smile 

Заработало хоть ?


--------------------
PM MAIL WWW   Вверх
Chupik
  Дата 23.4.2009, 21:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(GrayCardinal @  23.4.2009,  09:37 Найти цитируемый пост)
Заработало хоть ? 

Пока искал решение проблемы, в гугле нашёл компонент icq для делфи и сделал бота на нём... smile 

Думаю, потом доделаю этот проект(который на с++).

Это сообщение отредактировал(а) Chupik - 23.4.2009, 21:51
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Сети | Следующая тема »


 




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


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

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