• XSS.stack #1 – первый литературный журнал от юзеров форума

сервер

at0m

RAID-массив
Пользователь
Регистрация
16.05.2010
Сообщения
93
Реакции
2
Собственно нужно сделать реализацию большого кол-ва соединений и обработки данных.
Пока расматриваю платформу Windows. Насколько эффективно использовать socket's + обработка каждого соединения в отдельном потоке ? При средне статистичеких параметрах сервера (в реале ) сколько выдержить такой подход реализации соединений ? Есть более эффективные методы работы ?
 
на потоках неэффективно, ибо вопервых много ресурсов, во вторых переключение контекста сжирает очень много времени, в итоге такая схема не выдержит и 1000 клиентов одновременно, даже в спящем состоянии. Наиболее эффективной явл. схема с асинхронными сокетами с оверлаппед ио (по ивентам или коллбэкам) + несколько потоков количеством от N до 2*N (где N - количество ядер) обрабатывающие эти сокеты.
 
el-
libevent всегда! есть везде, даже с помощью пхп можно поднять демоны которые будут держать тысячи одновременных соединений.
есть инфа по теме ссылки ... ?
буду очень благодарен
 
гуглить
Код:
Completion Routines
немного проще реализация будет
Код:
IOCP
 
Вернулся опять к этой теме есть еще пара вопросов.
Ознакомился с IOCP вот есть ли смысл делать реализацию под Win32 кол-во клиентов будет около 3к-4к + еще на каждого припустим по 5 - 10 сессий открывать вот получится (свыше 20 к соединений ) на мое мнение врядли винда такое выдержит ?) может есть альтернативы к примеру node.js говорят ?
Есть окольные пути на php или лутше сразу копать в сторону unix демона и там все делать (есть ли готовое под никс ?)
 
at0m
во-первых многое зависит от железа. Серверная винда выдержит, если канал и железо позволит и архитектура ПО конечно. Лучше в таком случае лоад балансинг ещё прикрутить и распределять ботов по нескольким серверам. Вообще лучше думаю библиотеками воспользоватся типа asio, poco (правда они плюсовые, про чисто сишные не в курсе, но должны быть кросс-платформенные) для асинхроншины.
 
В общем вопрос такой делаю перенаправитель трафика на IOCP.
инициализация
BOOL Initialize(VOID)
{
BOOL bRet = FALSE;
if (InitWSA())
{
g_nThreads = WORKER_THREADS_PER_PROCESSOR * GetNumOfProcessors();
g_phWorkerThreads = new HANDLE[g_nThreads];
InitializeCriticalSection(&g_csConsole);
InitializeCriticalSection(&g_csClientList);
g_hShutdownEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
g_hIOCompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
if (g_hIOCompletionPort != NULL)
{
for (int i = 0; i < g_nThreads; i++)
{
g_phWorkerThreads[\i] = CreateThread(0, 0, MainThread, (LPVOID)g_hIOCompletionPort, 0,NULL);
}
// .......

}

}
return bRet;
}

вот так принимаю пиры

Initialize();
ADDRINFOA hints;
PADDRINFOA res;
MyZeroMemory(&hints,sizeof(hints),0);
if (IP_PROTOCOL_IPv4_IPv6 == 0xFF) hints.ai_family = PF_INET6;
if (IP_PROTOCOL_IPv4_IPv6 == 0x00) hints.ai_family = PF_INET;
hints.ai_flags = AI_PASSIVE;
hints.ai_socktype = SOCK_STREAM;
BOOL bAcceptConnectrions = FALSE;
SOCKET MainLocalListenSocket = INVALID_SOCKET;
WSAEVENT hMainLocalListenEvent = WSA_INVALID_EVENT;
if (getaddrinfo(NULL,DEFAULT_PORT,&hints,&res) == 0)
{
MainLocalListenSocket = WSASocket(res->ai_family,res->ai_socktype,res->ai_protocol,NULL,0,WSA_FLAG_OVERLAPPED);
if (MainLocalListenSocket != INVALID_SOCKET)
{
if (bind(MainLocalListenSocket,res->ai_addr,res->ai_addrlen) == 0 )
{
hMainLocalListenEvent = WSACreateEvent();
if (hMainLocalListenEvent != WSA_INVALID_EVENT )
{
if (WSAEventSelect(MainLocalListenSocket,hMainLocalListenEvent,FD_ACCEPT) == 0)
{
if (listen(MainLocalListenSocket,SOMAXCONN) == 0 )
{
bAcceptConnectrions = TRUE;
}
}
}
}
}
freeaddrinfo(res);
if (bAcceptConnectrions == TRUE)
{
while (TRUE)
{
DWORD dwRet = WSAWaitForMultipleEvents(1,&hMainLocalListenEvent,FALSE,INFINITE,FALSE);
switch (dwRet)
{
case WSA_WAIT_EVENT_0 + 0 :
{
WSANETWORKEVENTS WSANetworkEvents;
if (WSAEnumNetworkEvents(MainLocalListenSocket,hMainLocalListenEvent,&WSANetworkEvents) == 0)
{
if(WSANetworkEvents.lNetworkEvents & FD_ACCEPT)
{
if (WSANetworkEvents.iErrorCode[FD_ACCEPT_BIT] == 0)
{
SOCKADDR_STORAGE peer_sockaddr_storage;
int len_peer_sockaddr_storage = sizeof(SOCKADDR_STORAGE);
SOCKET sMainPeerSocket = WSAAccept(MainLocalListenSocket,(sockaddr*)&peer_sockaddr_storage,&len_peer_sockaddr_storage,NULL,0);
if (sMainPeerSocket != NULL)
{
PPEER_SOCKETS pPeerSockets = (PPEER_SOCKETS)GlobalAlloc(GMEM_ZEROINIT,sizeof(PEER_SOCKETS));

pPeerSockets->sPeerSocket = sMainPeerSocket;
CreateIoCompletionPort((HANDLE)sMainPeerSocket,g_hIOCompletionPort,(ULONG_PTR)pPeerSockets, 0);
PEER_IO_OPERATION_DATA PeerIoOperationData;
MyZeroMemory(&PeerIoOperationData.Overlapped,sizeof(WSAOVERLAPPED),0);
PeerIoOperationData.OperationType = IOAcceptData;
PeerIoOperationData.pBuffer = (PCHAR)GlobalAlloc(GMEM_ZEROINIT,BUFF_SIZE);
PeerIoOperationData.DataBuf.buf = PeerIoOperationData.pBuffer;
PeerIoOperationData.DataBuf.len = BUFF_SIZE;
BOOL bSuccess = PostQueuedCompletionStatus(g_hIOCompletionPort,0,(ULONG_PTR)pPeerSockets,&PeerIoOperationData.Overlapped);
if (!bSuccess && GetLastError( ) != ERROR_IO_PENDING)
{
GlobalFree(PeerIoOperationData.pBuffer);
GlobalFree(pPeerSockets);
continue;
}
}
}

}
}
}
case WSA_WAIT_FAILED:
{
break;
}
}
}
}
WSACloseEvent(hMainLocalListenEvent);
shutdown(MainLocalListenSocket,SD_BOTH);
closesocket(MainLocalListenSocket);
}

Проблема в том что немогу понять как правильно организовать следущее в рабочем потоке надо забиндить порт это не проблема а проблема в том как по этому порту принимать соединения так как пиров много, много будет и портов .....



DWORD WINAPI MainThread(LPVOID lpParam)
{
HANDLE hLocal_IOCompletionPort = (HANDLE)lpParam;
while(TRUE)
{
DWORD dwBytesTransferred;
PPEER_SOCKETS pPeerSockets;
PPEER_IO_OPERATION_DATA pPeerIoOperationData;
BOOL bRet = GetQueuedCompletionStatus(hLocal_IOCompletionPort,&dwBytesTransferred,(PULONG_PTR)&pPeerSockets,(LPOVERLAPPED*)&pPeerIoOperationData,INFINITE);


DWORD dwRecvBytes,dwFlags = 0;
int iError = WSARecv(pPeerSockets->sPeerSocket,&pPeerIoOperationData->DataBuf,1,&dwRecvBytes,&dwFlags,&pPeerIoOperationData->Overlapped,NULL);





}
return 0;
}


подскажите как правильно все организовать ?
спасибо за помощь
 
юзай тег code в следующий раз и посмотри вот этот блог, тут много про iocp http://young2code.wordpress.com/

Проблема в том что немогу понять как правильно организовать следущее в рабочем потоке надо забиндить порт это не проблема а проблема в том как по этому порту принимать соединения так как пиров много, много будет и портов .....

тут я не совсем понял что ты имеешь ввиду, сервер определяется как ip:port, порт который забинден тобой, клиенты ломятся на него и определяются так же как ip:port только порт в их случае находится на их машине и открывается для установления соединения с севером, при 100 конектов с одной машины будет открыто 100 локальных портов, дабы можно было отличить каждого из клиентов.
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх