И снова WinSock. UDP. Прием данных.

Рейтинг: 0Ответов: 1Опубликовано: 05.05.2011

До сих пор мучаюсь с изучением WinSock. Уже давно получилось послать команду серверу, но теперь не получается получить от него ответ. Буфер пишет какой-то мусор.

Дано: файл Unit1.cpp, sendrecieve.cpp, sendrecieve.h.
Требуется: после отправки серверу команды getstatus получить строку со всякими параметрами сервера.

Unit1.cpp:
Код занесен в секундный таймер.

char buf[1024];
sendCMD();
receiveINF(buf);
Memo1->Lines->Add(AnsiString(buf));

sendrecieve.h:
Две переменные для структуры sockaddr_in для функции sendCMD, которая посылает команду getstatus серверу и заголовки функций передачи/приема инфы.

extern char *serverIP;
extern int serverPORT;

void sendCMD();
void sendCMD(char *command);
void receiveINF(char *buf);

sendrecieve.cpp:
В функции receiveINF(char *buf) я попробовал сделать прием сокета, и вдобавок чтобы он был асинхорнный. В буфер, как я уже писал выше, идет какой-то мусор. Где-то я что-то делаю не так. Вот только не могу понять, где.

#include <vcl.h>
#include "sendreceive.h"
#include <winsock2.h>

#define WM_ONSOCKET WM_USER+1

void sendCMD()
{
    ...
}

void sendCMD(char *command)
{
    ...
}

void receiveINF(char *buf)
{
    int iResult = 0;

    WSADATA wsd;
    SOCKET RecvSocket;

    struct sockaddr_in RecvAddr;
    int RecvAddrSize = sizeof (RecvAddr);

// Инициализируем сокет
    iResult = WSAStartup(MAKEWORD(2,0), &wsd);
    if (iResult != NO_ERROR)
    {
        ShowMessage("WSAStartup filed");
    }

// Создаем принимающий сокет для приема датаграм
    RecvSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (RecvSocket == INVALID_SOCKET)
    {
        ShowMessage("Socket failed");
    }

//ВЫЗЫВАЕМ ФУНКЦИЮ, которая сделает нашу функцию АСИНХРОННОЙ. Где-то тут  
//точно есть косяк, о нём после описания данного файла. Скорее всего
//это: Application->Handle надо чем-то заменять. 
//И еще я не разобрался, что же такое WM_ONSOCKET (сверху он в define определен)
//p.s. эту функцию взял на просторах msdn и интернета, по этому не понял, что это
//за зверь. Может есть на что её поменять?
    WSAAsyncSelect(RecvSocket, Application->Handle, WM_ONSOCKET, FD_READ);

// Вызываем функцию для приема датаграм
    iResult = recvfrom(RecvSocket, buf, 1024, 0, (SOCKADDR *) & RecvAddr,
                                                               &RecvAddrSize);
    if (iResult == SOCKET_ERROR)
    {
        ShowMessage("Ошибка приема");
    }

// Закрываем сокет, когда приняли датаграммы
    iResult = closesocket(RecvSocket);
    if (iResult == SOCKET_ERROR)
    {
        ShowMessage("Ошибка закрытия сокета");
    }

//Очищаем все за собой, и выходим
    WSACleanup();
}

Собственно, косяк заключается в следующем: Когда запускаю программу, то в Memo1 ничего не пишется, но стоит мне мышкой навести на какое-нибудь окно, или кнопку любую, в Мемо1 будет писаться всякий мусор, видимо, из буфера. Причем если навести на кнопку курсор, и никуда не убирать его, то т.н. мусор будет все время одинаковый. Иногда, правда проскакивает "мусор", который, похоже, нужен мне - он начинается с юяяяя и дальше мусор (яяяя, это байты FF в UDP пакете, если точнее, то \xff\xff\xff\xff). И вопрос - я вообще правильно буфер подсовываю?:) Хотя делал strcat, в мемо с него всё нормально прочиталось.

Ответы

Ответов пока нет.