AKYLA, когда я в прошлом году сделал этот клиент я попробывал написать рассылку, но тут же столкнулся с проблемой минутного интервала. Писать обработку сообщений сервера мне было лень и я забросил эту идею. Попробуй, потестируй, погляди что возвращает сервер, обычно это сообщение (1036 вроде) в котором текстом в rtf объясняется причина по которой СМС не может быть доставлена.
Gar|k Ну я пока нашел ограничения это - минута, через 10 сообщений если тебе не отвечает абонент так же смс'кой то ты блокируешься на 24 часа. (хитро придумано, ведь ответные смс с тела на агент платные ))) Тесты показали, если с нового ака маил.ру пытаться отправить, ничего не будет, для этого обязательно нужно в контакты занести хотя бы один контакт с номером (потом его можно и удалить) и только тогда будет возможность отсылать без маил агента.
"Бороть" 50 СМС в сутки или 1 минуту не надо. В 1 поток быстрее чем 1 СМС в секунду не отшлешь. Решение - Вешаем 1К акков и вперед. По одному на секунду в цикле 50. Добавление/удаление телефона в контакты не нужно. Для отправки СМС нужно чтобы хотя бы в один контакт был добавлен номер телефона. Решение - добавляем любой "левый" номер в контакт Support (по умолчанию он у любого акка есть), а потом шлем СМС на любой нужный номер. Вот этот самый номер в контакты можно не писать. Все равно отправляет. Можно добавить проверку на наличие номеров в контактах акка, тогда вообще остается только отправить СМС-ку безо всяких добавлений. ИП вроде не "палится", но это надо массово проверять.. Удачных экспериментов.
Gar|k как думаеш это пдойдет для асинхронных ответов серверу ? отбработки ошибок нет для наглядности Code: typedef struct THREAD_INFO { CONST PCHAR pMsg; HANDLE hCompleteInit; } THREAD_INFO, *PTHREAD_INFO; DWORD WINAPI SendThread(PTHREAD_INFO th) { SOCKET s; PCHAR pMsg = malloc(strlen(th->pMsg)+1); strcpy(pMsg, th->pMsg); SetEvent(th->hCompleteInit); /* SendMsg выходиь из ожидания и завершается */ s = conct(MmpAddr); /* connect */ send(s, pMsg, strlen(pMsg), 0); free(pMsg); closesocket(s); return ERROR_SUCCESS; } VOID SendMsg(CONST PCHAR pMsg) { HANDLE hThread; THREAD_INFO th = {pMsg}; th.hCompleteInit = CreateEvent(NULL, FALSE, FALSE, NULL); hThread = CreateThread(NULL, 0, SendThread, &th, 0, NULL); WaitForSingleObject(th.hCompleteInit, INFINITE); CloseHandle(th.hCompleteInit); CloseHandle(hThread); } идея такая чтоб если надо часто отправлять ответы количество одновременно работающих потоков увеличивалось все равно они все на вводе выводе приостановятся чтоб отправлять за раз много ответов а когда запросы нечастые нет ни одного потока крутил крутил как сделать получилось это затраты на создание структур ядра потока и помещение его в очередь небольшие но все равно мне не нравится решение с постоянным созданием потоков сначал думал держать поток на событии но потом прикинул что мне надо например 10 потоков отправляли одновремено 10 событий ? 1 если собитые то или один поток проснется если с автосбросом или все если с ручным сбросом один если просыпатся будет неподходит так как отправка тогда не асинхронно будет выполнятся все тоже не пойдет если я передаю один запрос всего в минуту да и вот еще что допустим из какого то потока вызов SendMsg("MRIM_CS_HELLO"); так как вызов асихронный то она вернет управление и выйдет из функции ее вызывавшей буфер разрушится когда поток получит время начнет отсылать и прочитает из стека черти что поэтому пришлось сделать так тут блокируем вызывабщий поток пока поток когда получит время не скопирует себе строку в кучу Code: th.hCompleteInit = CreateEvent(NULL, FALSE, FALSE, NULL); hThread = CreateThread(NULL, 0, SendThread, &th, 0, NULL); WaitForSingleObject(th.hCompleteInit, INFINITE); а поток когда проснется первым делом скопирует строку Code: PCHAR pMsg = malloc(strlen(th->pMsg)+1); strcpy(pMsg, th->pMsg); SetEvent(th->hCompleteInit); маякнет вызывающему потоку что он закончил тот выйдет из вызова SendMsg("MRIM_CS_HELLO"); и можно уже не опасатся из какого контекста вызывалась функция фактически только задержка на событии для копирования строки получается но мне это не нравится как то есть идеи как лучше отправку организовать ? еще вариант с пулом поколдовать там хоть не надо создавать треды так часто QueueUserWorkItem в коде фактически придется только заменить CreateThread на QueueUserWorkItem наверно эффективней должно быть хоть потоки завершатся не будут набрел на твою статью решил поигратся с протоколом ))) кстати запости заголовок пакета которые отправляются перед сообщением который а то у меня маил агентов нет а ставить че то как то не очень то и надо )) фактически вот сразу попробовал решение с пулом потоков вот что получилось Code: typedef struct THREAD_INFO { CONST PCHAR pMsg; HANDLE hCompleteInit; } THREAD_INFO, *PTHREAD_INFO; DWORD WINAPI SendThread(PTHREAD_INFO th) { SOCKET s; PCHAR pMsg = malloc(strlen(th->pMsg)+1); strcpy(pMsg, th->pMsg); SetEvent(th->hCompleteInit); s = conct(MmpAddr); send(s, pMsg, strlen(pMsg), 0); free(pMsg); closesocket(s); return ERROR_SUCCESS; } VOID SendMsg(CONST PCHAR pMsg) { THREAD_INFO th = {pMsg}; th.hCompleteInit = CreateEvent(NULL, FALSE, FALSE, NULL); QueueUserWorkItem(SendThread, &th, WT_EXECUTEDEFAULT|WT_EXECUTELONGFUNCTION); WaitForSingleObject(th.hCompleteInit, INFINITE); CloseHandle(th.hCompleteInit); } работает много параллельных запросов из пула данные тоже корректно на событии копируются вызывающий поток который хочеит отправить сообщение ждет только пока потоку в пуле выделится время он скопирует пакет себе в память и тут же освобождает поток который хочет отправить сообщение уже что то )) есть мысли как сделать лучше ?))
greki_hoy посмотри это массив сокетов и те же потоки приема и отправки. (сейчас понимаю что прием лучше было бы реализовать через select) А вообще обмен с клиентом идет асинхронно... и стоит задуматься не проще ли использовать асинхронные сокеты? ) (я с ними никогда не работал... статейка так ничего) Вон прочитай выше статью и обрати внимание на описание WSAEventSelect. Я удмаю реально запихнуть весь клиент в одну функцию, а потом просто делать много потков на нее основе.