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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> ошибка recvfrom на клиенте, recvfrom на клиенте не принимает данные 
V
    Опции темы
DSan
Дата 2.6.2007, 00:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Имеется Win32 клиент-серверное приложение, использующее для обмена данными UDP дейтаграммы.

Серверная часть:
Код


Инициализация Сокетов...

void __fastcall TForm1::Button1Click(TObject *Sender)
{
    ServerSocket = socket(AF_INET, SOCK_DGRAM, 0);
    if(ServerSocket == INVALID_SOCKET)
    {
        MessageDlg("Socket() error!", mtError, TMsgDlgButtons() << mbOK, 0);
        return;
    }

    sockaddr_in ser_addr;
    ser_addr.sin_family = AF_INET;
    ser_addr.sin_port = htons(3333);
    ser_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    if(bind(ServerSocket,(sockaddr*) &ser_addr, sizeof(ser_addr)) != 0)
    {
        MessageDlg("Bind() error!", mtError, TMsgDlgButtons() << mbOK, 0);
        return;
    }

    id = 1;

    ServerThread = CreateThread(NULL, 0, ServerProc, NULL, 0, &ServerThreadID);
}

DWORD WINAPI ServerProc(void*)
{
    char buff[1024];

    while(1)
    {
        sockaddr_in cl_addr;
        int len_cl_addr = sizeof(cl_addr);
        int recsize = recvfrom(ServerSocket, &buff[0], sizeof(buff)-1,
                                0, (sockaddr*) &cl_addr, &len_cl_addr);
        if(recsize == SOCKET_ERROR)
        {
            MessageDlg("Receive error!", mtError, TMsgDlgButtons() << mbOK, 0);
            return 0;
        }

    ...
}


Клиентская часть:
Код

void __fastcall TForm1::Button3Click(TObject *Sender)
{
    ClientSocket = socket(AF_INET, SOCK_DGRAM, 0);
    if(ServerSocket == INVALID_SOCKET)
    {
        MessageDlg("Socket() error!", mtError, TMsgDlgButtons() << mbOK, 0);
        return;
    }

    id = 2;

    sockaddr_in dest_addr;

    dest_addr.sin_family = AF_INET;
    dest_addr.sin_port = htons(3333);
    dest_addr.sin_addr.s_addr = inet_addr(Edit1->Text.c_str());
    char buff[1024]  = "данные";
    sendto(ClientSocket, buff, strlen(buff), 0,
            (sockaddr *) &dest_addr, sizeof(dest_addr));

    ClientThread = CreateThread(NULL, 0, ClientProc, NULL, 0, &ClientThreadID);
}

DWORD WINAPI ClientProc(void*)
{
    char buff[1024];

    while(1)
    {
        sockaddr_in cl_addr;
        int len_cl_addr = sizeof(cl_addr);
        int recsize = recvfrom(ServerSocket, &buff[0], sizeof(buff)-1,
                                0, (sockaddr*) &cl_addr, &len_cl_addr);
        if(recsize == SOCKET_ERROR)
        {
            MessageDlg("Receive error!", mtError, TMsgDlgButtons() << mbOK, 0);
            return 0;
        }
     
     ...
}


Сервер получает и посылает данные, с ним все нормально.

Клиент посылать данные посылает, но принимать не хочет. Функция recvfrom не проходит, т.е. приложение не ждет пока данные придут, а просто проскакивает дальше и выдает ошибку Receive Error. Я так понимаю по той причине, что для ClientSocket-а не была явно вызвана функция bind, но ее невозможно вызвать на одной и той же машине второй раз, ведь порт уже "забинден" Серверной частью. По мануальчикам вычитал, что привязка к адресу должна осуществляться неявно при вызове таких функций как sendto, но почему-то не получается.
Для консольных приложений прокатывает и без bind, а в моем случае нет.

Что я делаю не так?

Это сообщение отредактировал(а) DSan - 2.6.2007, 00:26
PM   Вверх
ptr
Дата 2.6.2007, 09:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 661
Регистрация: 31.5.2006
Где: Новосибирск

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



Код

 int recsize = recvfrom(ServerSocket, &buff[0], sizeof(buff)-1,
                                0, (sockaddr*) &cl_addr, &len_cl_addr);

Видимо вместо ServerSocket надо ClientSocket.


--------------------
Единственный способ определить границы возможного - это выйти за эти границы, в невозможное.
Артур Кларк.
PM MAIL ICQ   Вверх
DSan
Дата 2.6.2007, 11:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(ptr @ 2.6.2007,  09:49)
Видимо вместо ServerSocket надо ClientSocket.

Блин, и правда.. Невнимательность..

Чтобы не создавать вторую тему, задам еще один вопрос здесь:
есть сокет, который посылает широковещательный запрос (настроен соответственно setsockopt(mysock, SOL_SOCKET, SO_BROADCAST, (char*)&sockopt, sizeof(sockopt)); ) 
Можно ли с помощью него получать ответные данные через recvfrom? Либо под это дело надо второй сокет приспосабливать?
PM   Вверх
ptr
Дата 4.6.2007, 14:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 661
Регистрация: 31.5.2006
Где: Новосибирск

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



По идее можно, но прежде надо сделать bind. Но зачем так делать? Тебе сложно завести ещё один сокет?


--------------------
Единственный способ определить границы возможного - это выйти за эти границы, в невозможное.
Артур Кларк.
PM MAIL ICQ   Вверх
DSan
Дата 7.6.2007, 21:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(ptr @ 4.6.2007,  14:55)
По идее можно, но прежде надо сделать bind. Но зачем так делать? Тебе сложно завести ещё один сокет?

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


 




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


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

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