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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Отправка TOP с сервера клиенту 
:(
    Опции темы
ddj
Дата 21.2.2010, 22:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



*Программа : сервер задает вапросы клиенту получает ответы.
Потсчитывает балы.записывает имя и балы в файл.
Позже считывает ети балы и сортирует.( делает топ лутших)
* работает так :
СЕРВЕР ->  КЛИЕНТ
имя? -> наме
        <-
далее подаются вопросы клиенту:
вопрос -> ответ
           <-
вопрос -> ответ
           <-
   ...       ....
когда вопросы заканчиваются выводятся балы:
 балы   ->  балы
далее в сервере есть ф-я которая записывает имя и балы в файл.
Позже сортирует ф-яй СОРТ и записывает в новый файл.( ТОП делает)

Проблема: Надо  выслать отсортированый ТОП к клиентy. Или ф-яй или файлам. Как ето сделать ?
пользуюсь етими ф-ями:

Код

#include <winsock2.h>
#include <Ws2tcpip.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>


Код

void send_line(int new_fd, char * Buffer) {
    send(new_fd, Buffer, strlen(Buffer)+1, 0);   
}

void recv_line(int new_fd, char * Buffer, int size) {
    int len = 0;    
    while (1) {
        int n = recv(new_fd, &Buffer[len], 1, 0);   
        if (n <= 0 || Buffer[len] == '\0')          
            break;                                  
        if (len < size - 1)                         
            len++;                                 
    }
    Buffer[len] = '\0';                              
}


...

Код

//...
while (fscanf (f, "%s %d", str, &taskai) != EOF)    
   {        
    //  printf ("%d", taskai);
     Vspisok (&pBeg, &pEnd, taskai, str);  
   }       
   printf("- - - - - - - - - - \n"); 
   
  Izspiska (pBeg);  
   printf("%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n",248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248);     
   printf ("TOP: \n");    
   mySort(pEnd);
//...


Может кто знает и может помоч...


Это сообщение отредактировал(а) ddj - 21.2.2010, 22:44
--------------------
#iddj
PM MAIL   Вверх
Олег2005
Дата 22.2.2010, 13:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Для отсылки целиком всего файла - вне зависимости от его размера, чтобы с буферами не заморачиваться, лучше всего использовать TransmitFile()
Cделали топ-файл и передали его дескриптор в функцию.
Функция TransmitFile() предназначена для посылки по сокетному соединению заранее открытого файла и в первую очередь предназначена для мощных серверных приложений, которые она избавляет от необходимости "вручную" открывать файл и многократно исполнять операцию чтения из файла с последующей передачей по сокету считанной порции. Вместо этого в функцию передаются дескрипторы сокета и открытого файла, и все дальнейшие операции по считыванию и передаче проходят на уровне ядра системы. Функция возвращает TRUE при успехе и FALSE при неудаче.
Данная функция позволяет быстро передать по сети данные из файла – так как если программа использует связку WSASend()/ReadFile(), то происходит многократное переключение между режимами ядра и пользовательским - функция TransmitFile() позволяет избежать этих переключений за счёт того что весь процесс чтения и отправки происходит целиком в режиме ядра. 
Код

BOOL PASCAL FAR TransmitFile (
    IN SOCKET        hSocket,
    IN HANDLE        hFile,
    IN DWORD        nNumberOfBytesToWrite,
    IN DWORD        nNumberOfBytesPerSend,
    IN LPOVERLAPPED    lpOverlapped,
    IN LPTRANSMIT_FILE_BUFFERS lpTransmitBuffers,
    IN DWORD        dwFlags
    );

Первый параметр – это соединенный сокет, им могут быть сокеты типа SOCK_STREAM, SOCK_SEQPACKET или SOCK_RDM, датаграммные сокеты не поддерживаются. Параметр hFile есть дескриптор уже открытого файла, и если указать его равным NULL, то передаче подлежит только определенная часть содержимого буфера lpTransmitBuffers. Параметр nNumberOfBytesToWrite представляет собой количество посылаемых из файла байтов, указание нуля означает пересылку всего содержимого файла. Параметр nNumberOfBytesPerSend определяет размер блока данных, посылаемых в рамках одной операции send(); если ноль, система использует размер by default, который для Windows NT Workstation равен 4k, а для Windows Server - 64k. Указание на структуру lpOverlapped не обязательно, и если оно отсутствует, то передача начинается с текущего положения указателя позиции файла. Уже упоминавшееся поле смещения в структуре OVERLAPPED в этом случае определяет место начала считывания файла. Необязательный параметр lpTransmitBuffers указывает на структуру TRANSMIT_FILE_BUFFERS, которая в свою очередь содержит указатели на буфера данных, содержание которых надо послать перед (или после) передачи файла. В таблице 4.4 приведены значения флагов, которые могут содержаться в необязательном параметре dwFlags.
Таблица 4.4 Флаги функции TransmitFile()
Флаг    Описание
TF_DISCONNECT    Стартует рассоединение на транспортном уровне, после того как все данные файла  помещены в очередь передачи.
TF_REUSE_SOCKET    Позволяет повторно использовать дескриптор сокета в AcceptEx() после завершения операции. Действителен только совместно с флагом  TF_DISCONNECT.
TF_USE_DEFAULT_WORKER    Указание системе использовать стандартный рабочий поток. Полезно при передаче больших объемов информации.
TF_USE_SYSTEM_THREAD    Указание системе использовать стандартный поток.
TF_USE_KERNEL_APC    Указание системе использовать для обработки "длинных" запросов асинхронные вызовы ядра системы (APC) вместо рабочих потоков. Длинные запросы TransmitFile() определяются как запросы, требующие  более чем одной операции чтения из файла или кэша.
TF_WRITE_BEHIND    Обозначает, что запрос TransmitFile() должен завершиться немедленно, даже если партнер по соединению не прислал соответствующее подтверждение приема. Не должен использоваться совместно с TF_DISCONNECT или TF_REUSE_SOCKET.
Примечание
Использование TF_USE_KERNEL_APC может быть  достаточно эффективно. Тем не менее возможно, что поток, в котором инициализирован контекст TransmitFile(),  используется для тяжелых вычислений, что  в свою очередь может предотвратить запуск  APC. Обратите внимание, что драйвер Winsock режима  ядра  использует  обычные APCs ядра, которые запускаются всякий раз, когда поток находится в состоянии ожидания, что отличается от APCs режима пользователя, которые запускаются всякий раз, когда поток находится в alertable состоянии ожидания, инициализированном в режиме пользователя.
Полная функциональность TransmitFile() обеспечивается только на серверных Windows-платформах.
В Windows XP/2003 появился ещё более раширенный набор "быстрых" WinSock функций - типа TransmitPackets().
Функция TransmitPackets() отличается от TransmitFile() тем, что она может отсылать как файлы, так и буферные блоки памяти в любом количестве и порядке и, в отличие от последней, обслуживает как TCP, так и UDP (в случае UDP для связывания сокета надо выполнить connect()). Она описывается так:
Код

BOOL (PASCAL FAR * LPFN_TRANSMITPACKETS) (
    SOCKET            hSocket,
    LPTRANSMIT_PACKETS_ELEMENT lpPacketArray,
    DWORD            nElementCount,
    DWORD            nSendSize,
    LPOVERLAPPED        lpOverlapped,
    DWORD            dwFlags
    );

Параметр lpPacketArray представляет собой указатель на массив, состоящий из нескольких специальных структур TRANSMIT_PACKETS_ELEMENT:
Код

typedef struct _TRANSMIT_PACKETS_ELEMENT {
ULONG dwElFlags;
ULONG cLength; // Количество передаваемых байтов. Если 0, то шлется весь файл.
union {struct 
        {
             LARGE_INTEGER nFileOffset;    // Смещение точки передачи в файле
             HANDLE        hFile;        // Дескриптор открытого файла
         };
        PVOID             pBuffer;        // Указатель на буфер в памяти
    };
} TRANSMIT_PACKETS_ELEMENT;


Поле dwElFlags этой структуры содержит флаги, определяющие содержание элемента массива lpPacketArray, например TP_ELEMENT_MEMORY, TP_ELEMENT_FILE или TP_ELEMENT_EOP – последний определяет гранулярность операции send(). 
Возвратимся к описанию функции. Параметр nElementCount определяет количество элементов массива TRANSMIT_PACKETS_ELEMENT, nSendSize аналогичен параметру nNumberOfBytesPerSend функции TransmtFile(), параметр lpOverlapped (необязателен) – очевиден. Значение флагов указано в таблице 4.4 за исключением префикса – он должен быть TP. Флаги TP_DISCONNECT и TP_REUSE_SOCKET для датаграммной передачи не имеют смысла и их указание приводит к ошибке. Кроме того, некоторые комбинации флагов противоречивы и за этим должен следить программист. Функция возвращает TRUE при успехе и FALSE при неудаче.


Это сообщение отредактировал(а) Олег2005 - 22.2.2010, 13:11
PM MAIL WWW MSN   Вверх
ddj
Дата 22.2.2010, 20:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



А как небудь просче ? Чтобы только функцию высылать ?
Есть :  mySort(pEnd); // выводит в сервере на экран топ.
И как сейчас эту ф-ю послать клиенту ?

--------------------
#iddj
PM MAIL   Вверх
Олег2005
Дата 23.2.2010, 12:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(ddj @  22.2.2010,  19:59 Найти цитируемый пост)
А как небудь просче ? Чтобы только функцию высылать ?

Никак.
В сетевом общении - не передаются функции - в крайнем случае их можно удаленно запустить (протокол RPC).
Но для любой функции - нужны данные.
Вот сеть и передает эти данные. 
И то, что я вам предложил - это самый простой способ.
Клиенту вы передаете данные. 
Клиент получает их - делает вызов процедуры визуализации данных - и выводит например на экран.
Принципиально - можно объекный код функции в виде бинарного файла отправить клиенту - он клиент должен будет скомпоновать из этого бинарного файла экзкшник, получить данные, передать данные в экзашник - и запустить.
Все это не стоит свеч.
Проще иметь на непосредственно на клиенте программу визуализации - и по получении данных ее запускать....



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


 




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


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

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