Автор
|
Тема: Перекачка по сокетам >15К.
|
server_mouse |
опубликован 08-10-2001 23:32 MSK
Привет всем! Как правильно делать сабж? Если я делаю примерно так char buf[20*1024]; send(sock,buf,20*1024,NULL); то на стороне клиента приходит сообщение FD_READ, я делаю recv(...) и получаю порядка 5 килобайт. После опять приходит FD_READ, но recv(...) возвращает SOCKET_ERROR, а WSAGetLastError() даёт WSA_QOS_TRAFFIC_CTRL_ERROR (WSABASEERR + 1014) Чё делать??? Причём ошибка непереодическая. в 20% случаев доходят сразу все 20К!
|
purpe
|
опубликован 09-10-2001 00:07 MSK
вот тут, мне кажется, тебе самое время взглянуть, как этот механизм реализован в примере вебсервера, поставляемого в комплекте с VC.
|
Demo_S
|
опубликован 11-10-2001 03:25 MSK
Кстати,намыль если не жалко тот кусок, когда ты определяешь, что пришло тебе FD_READ а потом пускаешь recv. (Я так понимаю,что тут задествован accept, а вот как с ним работать я до конца и не разобрался). |
server_mouse
|
опубликован 11-10-2001 11:46 MSK
Разобрался... Сделал по-другому recv и всё заработало. Что не работало в предыдущей реализации для меня осталось секретом.2Demo_S : #define MesZag (sizeof(mes->cmd)+sizeof(mes->len)) if( WSA_WAIT_FAILED != ::WSAWaitForMultipleEvents(1, &hEvent, false,50,false)) { WSANETWORKEVENTS NetEv; if(0==WSAEnumNetworkEvents(MyClass->sock,hEvent,&NetEv)) { if(NetEv.lNetworkEvents & FD_READ) { if(NetEv.iErrorCode[FD_READ_BIT] == 0) {//Читаем наш заголовок не убирая его из буфера Mess* mes=(Mess*)new char[MesZag+1]; i=recv(MyClass->sock,(char*)mes,MesZag+1,MSG_PEEK); //Ну и здесь узнав по заголовку длинну //освобождаем нужный кусок памяти if(i!=SOCKET_ERROR) { int BufLen=MesZag+mes->len; delete mes; mes=(Mess*)new char[BufLen]; //Забираем всю месагу из буфера //На самом деле этот процесс намного сложнее, //поскольку месага может быть слишком длинной, //что бы забраться за один присет. i=recv(MyClass->sock,(char*)mes,BufLen,NULL); //ну и дальше лопатим пришедшее сообщение }//if(i!=SOCKET_ERROR) }//if(NetEv.iErrorCode }//if(NetEv.lNetworkEvents&FD_READ //А здесь можно вставить реакцию //на др. сетевые события, например FD_ACCEPT else if(NetEv.lNetworkEvents & FD_ACCEPT) { if(NetEv.iErrorCode[FD_ACCEPT_BIT] == 0) { //Здесь создаёшь новый сокет, делаешь ему accept //и запускаешь отдельный поток обрабатывающий //события от этого сокета тем-же способом. //Ну и конечно, что бы не потерять свои потоки //создаёшь из них очередь. } } }//if(0==WSAEnumNetworkEvents }//if( WSA_WAIT_FAILED!=::WSAWaitForMultipleEvents Примерно так... А что касается accept, то на него приходит FD_ACCEPT (см. выше)
|
purpe
|
опубликован 11-10-2001 13:01 MSK
2server_mouse: и всё-таки через MFC всё будет намного корректнее:CByteArray m_buf; m_buf.SetSize(1024); int nBytes = CAsyncSocket.Receive(m_buf.GetData(), m_buf.GetSize()); if (nBytes != SOCKET_ERROR) { // и пошло и поехало ... и не нада думать о размерах буфера и однозначно всё примется ... но это чиста моё мнение :)
|
Emerald
|
опубликован 11-10-2001 14:19 MSK
(тихо смеясь) - Winsock ActiveX Rulezzzz. :) |
server_mouse
|
опубликован 11-10-2001 17:47 MSK
LowLevel -- it's my loveИ чем ниже, тем лучше... ;) |
Demo_S
|
опубликован 14-10-2001 02:20 MSK
2server_mouse Спасибо.>>LowLevel -- it's my love Стал за собой замечать такие же проявления >>И чем ниже, тем лучше... ;) ниже только мыши:))
и еще просто фукции sebd,recv,accept без WSA, ток я в этом accept так и не разобрался... мутил все через окна и AsyncSocket. а send/recv работает круто:) |