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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> send не отсылает данные на сервер, winsock2 
V
    Опции темы
Arks
Дата 30.1.2009, 18:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Клиент-серверное приложение.
В общем, надо сделать примитив синхронизации - канал. Решил сделать так:
1. На клиенте создаётся канал, он отправляет команды на сервер, там создаётся новый примитив канал (у меня уже нормальный канал, который для межпроцессорного взаимодействия предназначен).
В общем клиенты посылают команды и получают ответы сервера.

Если начал делать в корне не верно, поправьте меня - первый раз в жизни с сокетами дело имею.
Итак:
клиент создаёт сокет, соединяется с сервером - тут всё нормально. Но вот функция send() возвращает код ошибки и соответсвенно ничего серверу не посылает. Не знаю почему. На первый взгляд, всё до этого момента идёт нормально и код этот везде до этой функции send() просто скопирован из msdn (в ней пример есть, конечно же, рабочий).

УТОЧНЮ: send() возвращает SOCKER_ERROR, а дальшейший вызов WSAGetLastError() возвращает код 10014 (WSAEFAULT).

Собственно код:

На стороне клиента:
Код

try
    {
        NetworkChannel *ch = new NetworkChannel(STANDARD_CHANNEL_DEPTH, STANDARD_CHANNEL_TIMEOUT, L"testch",
            "127.0.0.1", DEFAULT_PORT);

        delete ch;
    }
    catch(int err)
    {
        printf("exception in NetworkChannel constructor: %d\n", err);
    }

    _getch();
    return 0;


1. Конструктор канала:
Код

NetworkChannel::NetworkChannel(int max_depth, int def_timeout, wchar_t *name, char *server_ip, char *server_port)
{
    // Создаём новый канал
    socket = OpenSocket(server_ip, server_port);
    if(socket == INVALID_SOCKET)
        throw 0;

    // отправляем запрос на сервер
    int iResult;
    ChannelCreateStruct ch;
    ch.max_depth = max_depth;
    ch.def_timeout = def_timeout;
    ch.name_length = wcslen(name);

    // запросим создание нового канала
    printf("CHANNEL_OPEN_COMMAND = %d", (int)CHANNEL_OPEN_COMMAND);
    printf("sizeof(int) = %d\tsizeof(CHANNEL_OPEN_COMMAND) = %d\n", (int)sizeof(int), sizeof((char*)((int)CHANNEL_OPEN_COMMAND)));

  //  ВОТ ЭТОТ SEND() ВОЗВРАЩАЕТ ОШИБКУ                                         !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    iResult = send(socket, (char*)((int)CHANNEL_OPEN_COMMAND), (int)sizeof(int), 0);
  // !!!!!!!!!!                                                                                              !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    if(iResult == SOCKET_ERROR)
    {
        printf("Network channel: socket error on CHANNEL_OPEN_COMMAND send\n");
        closesocket(socket);
        WSACleanup();
        throw 1;
    }
    
    ... // другие запросы
}


2. Функция OpenSocket:
Код

SOCKET OpenSocket(char *ip, char *port)
{
    int iResult;
    WSADATA wsaData;
    SOCKET ConnectSocket = INVALID_SOCKET;
    struct addrinfo *result = NULL,
                    *ptr = NULL,
                    hints;

    iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
    if (iResult != 0) {
        printf("WSAStartup failed: %d\n", iResult);
        _getch();
        return INVALID_SOCKET;
    }

    ZeroMemory( &hints, sizeof(hints) );
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    // Resolve the server address and port
    iResult = getaddrinfo(ip, port, &hints, &result);
    if ( iResult != 0 ) {
        printf("getaddrinfo failed: %d\n", iResult);
        WSACleanup();
        _getch();
        return INVALID_SOCKET;
    }

    // Attempt to connect to an address until one succeeds
    for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) {

        // Create a SOCKET for connecting to server
        ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, 
            ptr->ai_protocol);
        if (ConnectSocket == INVALID_SOCKET) {
            printf("Error at socket(): %ld\n", WSAGetLastError());
            freeaddrinfo(result);
            WSACleanup();
            _getch();
            return INVALID_SOCKET;
        }

        // Connect to server.
        iResult = connect( ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
        if (iResult == SOCKET_ERROR) {
            closesocket(ConnectSocket);
            ConnectSocket = INVALID_SOCKET;
            continue;
        }
        break;
    }

    freeaddrinfo(result);

    if (ConnectSocket == INVALID_SOCKET) {
        printf("Unable to connect to server!\n");
        WSACleanup();
        _getch();
        return INVALID_SOCKET;
    }

    return ConnectSocket;
}



Серверный код:
Код

int _tmain(int argc, _TCHAR* argv[])
{
    WSADATA wsaData;
    int iResult;

    // Инициализировать Winsock
    iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if(iResult != 0)
    {
        printf("WSAStartup failed: %d\n", iResult);
        _getch();
        return 1;
    }

    struct addrinfo *result = NULL, *ptr = NULL, hints;

    ZeroMemory(&hints, sizeof(hints));
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;
    hints.ai_flags = AI_PASSIVE;

    // Resolve the local address and port to be used by the server
    iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
    if ( iResult != 0 )
    {
        printf("getaddrinfo failed: %d\n", iResult);
        WSACleanup();
        _getch();
        return 1;
    }

    SOCKET ListenSocket = INVALID_SOCKET;

    // Create a SOCKET for the server to listen for client connections
    ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);

    if (ListenSocket == INVALID_SOCKET)
    {
        printf("Error at socket(): %ld\n", WSAGetLastError());
        freeaddrinfo(result);
        WSACleanup();
        _getch();
        return 1;
    }

    // Setup the TCP listening socket
    iResult = bind( ListenSocket, 
        result->ai_addr, (int)result->ai_addrlen);
    if (iResult == SOCKET_ERROR)
    {
        printf("bind failed: %d\n", WSAGetLastError());
        freeaddrinfo(result);
        closesocket(ListenSocket);
        WSACleanup();
        _getch();
        return 1;
    }

    if ( listen( ListenSocket, SOMAXCONN ) == SOCKET_ERROR )
    {
        printf( "Error at listen(): %ld\n", WSAGetLastError() );
        closesocket(ListenSocket);
        WSACleanup();
        _getch();
        return 1;
    }

    SOCKET ClientSocket;

    vector<HANDLE> handle;
    
    //do
    //{
        ClientSocket = INVALID_SOCKET;

        // Accept a client socket
        ClientSocket = accept(ListenSocket, NULL, NULL);
        if (ClientSocket == INVALID_SOCKET)
        {
            printf("accept failed: %d\n", WSAGetLastError());
            closesocket(ListenSocket);
            WSACleanup();
            _getch();
            return 1;
        }
        
        // создаём новый поток, где и обрабатываем сокет
        HANDLE h = CreateThread(NULL, 0, &ServerWork, (void*)ClientSocket, 0, NULL);
        handle.push_back(h);

        //HANDLE server_handle = (HANDLE)_beginthreadex(NULL, 0, &ServerWork, (void*)ClientSocket, 0, NULL);

        if(_kbhit())
        {
            if(_getch() == 'x')
                ;//break;
        }
    //}while(1);

    for(vector<HANDLE>::iterator i = handle.begin(); i != handle.end(); i++)
    {
        WaitForSingleObject((HANDLE)*i, INFINITE);
        CloseHandle(*i);
    }

    _getch();
    return 0;
}

DWORD WINAPI ServerWork(LPVOID socket)
{
    SOCKET ClientSocket = (SOCKET)socket;

    char *recvbuf;
    int iSendResult;
    int recvbuflen = (int)sizeof(int);
    int iResult;

    // Взяли команду
    recvbuf = new char[recvbuflen];
    printf("recvbuflen = %d\tsizeof(recvbuf) = %d\n", recvbuflen, sizeof(recvbuf));
    iResult = recv(ClientSocket, recvbuf, recvbuflen, 0);
    printf("recvbuf = ");
    puts(recvbuf);
    if(iResult <= 0)
        goto shutdown_socket;
    int command;
    memcpy(&command, recvbuf, sizeof(int));
    printf("command = %d", command);

    . . . // обработка следующих запросов
}


Кроме того, я проверял, чтобы размеры буфера были одинаковые и там и там, кроме того указывал длину (int)sizeof(int)+1, тоже ничего не изменило.


Это сообщение отредактировал(а) Arks - 30.1.2009, 23:09
PM MAIL ICQ Skype MSN   Вверх
Arks
Дата 30.1.2009, 23:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Так-с, зря такое длинное сообщение накатал.
Ошибка была вот тут:
Код

iResult = send(socket, (char*)((int)CHANNEL_OPEN_COMMAND), (int)sizeof(int), 0);


Передавать-то вообще-то надо в функцию указатель, а не значение. От того сокеты и выдавали ошибку о неверном адресе указателя.
Вот так всё работает:
Код

int buf;
iResult = send(socket, (char*)&buf, (int)sizeof(int), 0);

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


 




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


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

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