Сокеты и потоки. Обмен данными между ними.
От: Аноним  
Дата: 20.02.03 06:30
Оценка:
Подскажите пожалуйста: создан сервис для обработки соединений TCP.
При подключении каждого клиента, создается новый поток.
Как при получении данных от одного клиента, передать их другому клиенту.
Подскажите оптимальный вариант. Спасибо.
Re: Сокеты и потоки. Обмен данными между ними.
От: Аноним  
Дата: 20.02.03 06:59
Оценка:
Здравствуйте, Аноним, Вы писали:
А>Подскажите пожалуйста: создан сервис для обработки соединений TCP.
А>При подключении каждого клиента, создается новый поток.
А>Как при получении данных от одного клиента, передать их другому клиенту.

если речь идет об организации очередей — лучше (win32) использовать встроенные ср-ва системы — message queue: PostThreadMessage.
Re[2]: Сокеты и потоки. Обмен данными между ними.
От: Аноним  
Дата: 20.02.03 08:45
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Аноним, Вы писали:

А>>Подскажите пожалуйста: создан сервис для обработки соединений TCP.
А>>При подключении каждого клиента, создается новый поток.
А>>Как при получении данных от одного клиента, передать их другому клиенту.

А>если речь идет об организации очередей — лучше (win32) использовать встроенные ср-ва системы — message queue: PostThreadMessage.


А это будет работать в потоках без окна? Т.е. как получать сообщения?
Re[3]: Сокеты и потоки. Обмен данными между ними.
От: Аноним  
Дата: 20.02.03 08:53
Оценка:
Здравствуйте, Аноним, Вы писали:

А>А это будет работать в потоках без окна? Т.е. как получать сообщения?


Да.
получать сообщения как обычно PeekMessage, GetMessage c hWnd = NULL
ожидать поступление сообщений по MsgWaitForMultipleObjects
Re[3]: Сокеты и потоки. Обмен данными между ними.
От: Barzini  
Дата: 20.02.03 08:54
Оценка: -1
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Аноним, Вы писали:


А>>Здравствуйте, Аноним, Вы писали:

А>>>Подскажите пожалуйста: создан сервис для обработки соединений TCP.
А>>>При подключении каждого клиента, создается новый поток.
А>>>Как при получении данных от одного клиента, передать их другому клиенту.

А>>если речь идет об организации очередей — лучше (win32) использовать встроенные ср-ва системы — message queue: PostThreadMessage.


А>А это будет работать в потоках без окна? Т.е. как получать сообщения?


В потоках без окна это не работает, можно через обычные эвенты организовать.
Re[4]: Сокеты и потоки. Обмен данными между ними.
От: ВованЯ  
Дата: 20.02.03 09:58
Оценка:
Здравствуйте, Barzini, Вы писали:
B>В потоках без окна это не работает,

к счастью это работает в потоках без окон.
вот пример кода потока, который создает для себя очередь сообщений (см.выделение) и работает с сообщениями, каторые к нему шлют по PostThreadMessage.

DWORD WINAPI MainThread(LPVOID lpParameter)
{   MSG                    msg;
    HANDLE            hWaitList[2];// массив событий синхронизации работы thread
    BOOL                bExit    =FALSE;
    
    // создадим очередь сообщений thread
    PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
        
    hWaitList[0]=hQuit;        // сигнал от основной программы на завершение работы thread
    
    while(!bExit)    // повторяем цикл пока не будет установлен признак завершения работы
    { if(MsgWaitForMultipleObjects(1, hWaitList, FALSE, INFINITE, QS_ALLEVENTS)==WAIT_FAILED){ bExit=TRUE; break;}

        // пометить все события в очереди, что бы они не были "новыми" 
        // и не вызывали срабатывания ожидания при след. MsgWaitForMultipleObjects
        // до прихода действительно новых сообщений от осн. программы 
        GetQueueStatus(QS_ALLEVENTS);
        // это нужно для того чтобы можно было оставлять непрочитанные сообщения в очереди до тех пор, 
        // пока информация в них не понадобится для вывода (записи) в файл
    
        // проверим, не было ли запроса от осн. программы на завершение работы
        if(WaitForSingleObject(hQuit, 0)==WAIT_OBJECT_0){ bExit=TRUE; break; }

        // цикл выборки сообщений из входной очереди thread
        while(PeekMessage(&msg, (HWND)(INVALID_HANDLE_VALUE), 0, 0, PM_REMOVE))
        {
        }        
    }
    return(0);
}
С уважением, Владимир
Re[4]: Сокеты и потоки. Обмен данными между ними.
От: Аноним  
Дата: 20.02.03 12:16
Оценка:
Создал сообщения, пришлось для каждого клиента запускать еще один процесс, для получения
сообщений (это хорошо? есть другие варианты в данном случае?). Столкнулся с проблемой: все потоки сообщение получают, но
отправка данных клиенту работает только в том потоке, который отправил серверу "ALL". (причем send() везде возвращает нормальное значение)
Почему не работает отправка в других потоках?


DWORD id[10]={0,0,0,0,0,0,0,0,0,0};
int count = 0;
#define WM_ALLUSERS WM_USER+1000

main(){
...
client = accept(server,(sockaddr*)&sin_c,&i);
// создаем поток на каждого клиента
CreateThread(NULL,0,ThreadClient,(LPVOID)client,0,0);
...
}

DWORD WINAPI ThreadClient(LPVOID lpPar){
SOCKET client = (SOCKET) lpPar;
char buf[512];

// создаем поток каждому клиенту для получения сообщений
CreateThread(NULL,0,ThreadForMessage,(LPVOID)client,0,&id[count]);
count++;

memset(buf,0,512);
while(true){
int i = recv(client,buf,512,0); if(i<1) break;
if(lstrcmpi(buf,"ALL") == 0){
for(int index = 0;index <= count;index++){ // отправляем всем потокам сообщение
PostThreadMessage(id[index],WM_ALLUSERS,0,0);
}
}
memset(buf,0,i);
}
...
}

DWORD WINAPI ThreadForMessage(LPVOID lpParam){
SOCKET client = (SOCKET) lpParam;
MSG Msg;
while(true){
if(GetMessage(&Msg,NULL,0,0)){
if(Msg.message == WM_ALLUSERS){
int n = send(client,"I'm get message\0",16,0);
if(n==SOCKET_ERROR){
printf("\nError: %h",WSAGetLastError());
}else{
printf("\nSend: %d byte",n);
}
}
}
}
}
Re[5]: Сокеты и потоки. Обмен данными между ними.
От: Barzini  
Дата: 20.02.03 12:41
Оценка:
Здравствуйте, ВованЯ, Вы писали:

ВЯ>Здравствуйте, Barzini, Вы писали:

B>>В потоках без окна это не работает,

ВЯ>к счастью это работает в потоках без окон.

ВЯ>вот пример кода потока, который создает для себя очередь сообщений (см.выделение) и работает с сообщениями, каторые к нему шлют по PostThreadMessage.

Да, прошу прощения, про обычный цикл сообщений я и забыл. Крыша едет спохмела
Re[5]: Сокеты и потоки. Обмен данными между ними.
От: SCS  
Дата: 20.02.03 12:46
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Создал сообщения, пришлось для каждого клиента запускать еще один процесс, для получения

А>сообщений (это хорошо? есть другие варианты в данном случае?). Столкнулся с проблемой: все потоки сообщение получают, но
А>отправка данных клиенту работает только в том потоке, который отправил серверу "ALL". (причем send() везде возвращает нормальное значение)
А>Почему не работает отправка в других потоках?

А>    // создаем поток каждому клиенту для получения сообщений
А>    CreateThread(NULL,0,ThreadForMessage,(LPVOID)client,0,&id[count]);
А>    count++;

а вот здесь у тебя может возникнуть баг, count++ — этот оператор может выполняться не в том порядке, в котором ты стартуешь потоки.
А>    SOCKET client = (SOCKET) lpParam;

IMHO
наверное можно сделать duplicate для сокета. у тебя в одном потоке на нем висит синхронное чтение, а из другого потока ты что-то выводишь в сокет. похоже в буфере данные для передачи запомнились, но ни куда не передавались. (причем сокет, который принял сообщение, оправил ответ — на нем не было никакой текущей операции)



по организации — лучше использовать только один поток и асинхронный ввод/вывод по сокету.
SCS
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.