Re[34]: winsock и порты завершения ввода-вывода
От: Pepel Беларусь  
Дата: 20.04.09 09:41
Оценка:
спасибо, на vmware в холодном чулане 2003 сервак крутится, вообщем как вариант
Re[35]: winsock и порты завершения ввода-вывода
От: Pepel Беларусь  
Дата: 20.04.09 14:43
Оценка:
maxlosyam, построил ConnectEx() по приведенному Вами сценарию, получаю :

WSAEINVAL — The parameter s is an unbound or a listening socket.

и действительно, msdn по ConnectEx() :

Parameters
s [in] Descriptor identifying an unconnected, previously bound socket.

но это же 'клиент идущий на сервер' зачем и куда этот сокет биндить ?
Re[36]: winsock и порты завершения ввода-вывода
От: Pepel Беларусь  
Дата: 20.04.09 15:38
Оценка:
похож тут классическую теорию сокетов над немножко шире понимать, потому как bind() в данном случае нужен, чтобы ConnectEx() отработал, в качестве адреса передал

INADDR_ANY ; // любой адрес — локальный

отработало успешно,

такое вот требование у ConnectEx() значит, так ?
Re[37]: winsock и порты завершения ввода-вывода
От: maxlosyam Россия  
Дата: 20.04.09 16:47
Оценка: 2 (1)
Здравствуйте, Pepel, Вы писали:

P>похож тут классическую теорию сокетов над немножко шире понимать, потому как bind() в данном случае нужен, чтобы ConnectEx() отработал, в качестве адреса передал


P>INADDR_ANY ; // любой адрес — локальный


P>отработало успешно,


P>такое вот требование у ConnectEx() значит, так ?


да сокет для ConnectEx надо сначала bind'ануть
видимо сделали для каких-то случаев чтобы конектиться с определенных интерфейсов целенаправлено игнорируя роутинг

bool IOSocket::Connect(const unsigned long uDest, const unsigned short uPort, unsigned long uBindAddr /* = INADDR_ANY */ , IOBuffer* pBuffer)
{
    assert(m_pConnectEx);
    assert(m_hSocket != SOCKET(INVALID_SOCKET));
    if(m_hSocket == SOCKET(INVALID_SOCKET)) // INVALID_SOCKET приведен в SOCKET потому чтобы небыло проблемм при сравнении на x64
        return false;
    sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_addr.S_un.S_addr = uBindAddr;
    addr.sin_port = 0;
    if(SOCKET_ERROR == bind(m_hSocket,(SOCKADDR*)&addr,sizeof(SOCKADDR)))
        return false;
    addr.sin_addr.S_un.S_addr = uDest;
    addr.sin_port = htons(uPort);
    DWORD dwSent = 0;
    BOOL bRet = m_pConnectEx(m_hSocket
        ,(const sockaddr*)&addr
        ,sizeof(SOCKADDR)
        ,pBuffer->GetBuffer(),DWORD(pBuffer->GetSize()),&dwSent,pBuffer);
    int nError = WSAGetLastError();
    if(!bRet && nError != ERROR_IO_PENDING)
        return false;
    return true;
}
Re[38]: winsock и порты завершения ввода-вывода
От: Pepel Беларусь  
Дата: 21.04.09 12:12
Оценка:
Касатально WSASend () :

MSDN : The successful completion of a WSASend does not indicate that the data was successfully delivered.

как понимать эту тезу — delivered — о доставке кому идет речь, точнее о "НЕ ГАРАНТИИ" доставки на каком уровне говорится ? tcp это ж reliable протокол, я передал данные WSASend () — она вернула 'успех' — значит они уже в стеке сетевого интерфейса принимающей стороны, так ? об чем речь тогда ?
Re[39]: winsock и порты завершения ввода-вывода
От: maxlosyam Россия  
Дата: 21.04.09 14:26
Оценка: 2 (1)
Здравствуйте, Pepel, Вы писали:

P>Касатально WSASend () :


P>MSDN : The successful completion of a WSASend does not indicate that the data was successfully delivered.


P>как понимать эту тезу — delivered — о доставке кому идет речь, точнее о "НЕ ГАРАНТИИ" доставки на каком уровне говорится ? tcp это ж reliable протокол, я передал данные WSASend () — она вернула 'успех' — значит они уже в стеке сетевого интерфейса принимающей стороны, так ? об чем речь тогда ?


это не относится к IOCP, если сокет был скормлен порту завершения то тотже WSASend работает просто типа как PostQueuedCompletionStatus всегда возвращая WSA_IO_PENDING, в IOCP ошибки обрабатываются только в рабочих потоках
BOOL bRet = GetQueuedCompletionStatus(hIOPortHandle,&dwTransferred,&uCompletionKey,&pOverlapped,INFINITE);
DWORD dwRet = GetLastError();
if(bRet) dwRet = ERROR_SUCCESS;    
switch(dwRet)
{
      case ERROR_SUCCESS:
           // do something usefull
           break;
      case WAIT_TIMEOUT:
           // WTF!?!?!?!?
           break;
      default:
           // :(
           break;
}
Re[40]: winsock и порты завершения ввода-вывода
От: Pepel Беларусь  
Дата: 21.04.09 14:48
Оценка:
спасибо!

maxlosyam, здесь мне кажется тут нечто концептуальное сообщается, безотносительно к тому, асинхронный вызов отсылки данных либо синхронный, такая ж приписка есть и к функции send() .. к слову, мне сдается это вообще обозначение того, что успешное завершение функции отсылки данных в сокет (не важно где мы это завершение ловим) нифига не гарантирует их доставку ?? тоесть шлю я WSASend() (ну либо тупо send()) 200 байт, словил в первом случае на IOCP успешное завершение — это не гарантия, что на той стороне эти данные были получены, так ?
Re[41]: winsock и порты завершения ввода-вывода
От: maxlosyam Россия  
Дата: 21.04.09 15:35
Оценка: 2 (1)
Здравствуйте, Pepel, Вы писали:

P>спасибо!


P>maxlosyam, здесь мне кажется тут нечто концептуальное сообщается, безотносительно к тому, асинхронный вызов отсылки данных либо синхронный, такая ж приписка есть и к функции send() .. к слову, мне сдается это вообще обозначение того, что успешное завершение функции отсылки данных в сокет (не важно где мы это завершение ловим) нифига не гарантирует их доставку ?? тоесть шлю я WSASend() (ну либо тупо send()) 200 байт, словил в первом случае на IOCP успешное завершение — это не гарантия, что на той стороне эти данные были получены, так ?


ну send то тут причем? он overlapped структурку никаким боком не кушает.

IOCP это совершенно другая песня, тупо говоря сам порт завершения уже нечто вроде "сервера" (механизм), ты ему передаешь запросы, он их выполняет и дает тебе результаты. все остальное это просто фукнции для общения с IOCP. все эти приписки относятся к blocking, non-blocking и overlapped сокетам, в случае с IOCP всю работу с сокетами берет на себя сам IOCP, это уже его проблеммы как правильно обрабатывать эти "приписки". у тебя роль уже простая, правильно давать порту завершения запросы и обрабатывать его ответы.

сценарий отправки через IOCP выглядит примерно так
1. ты через WSASend передаешь IOCP данные на отправку, если все ок WSASend возвращает SOCKET_ERROR и WSA_IO_PENDING в last error
2. IOCP делает MAGICK VOODOO VOODOO и помещает результат в очередь выполенных запросов
3. ты через GetQueuedCompletionStatus получаешь результат из этой очереди, в результате уже есть вся инфа, т.е либо отправка была ок и сколько байт 100% было отправлено, либо ошибку о том что оправка вообще обламалась.

т.е тупо говоря всю кухню за тебя делает сам IOCP
Re[41]: winsock и порты завершения ввода-вывода
От: perf13  
Дата: 21.04.09 15:37
Оценка: 2 (1)
Здравствуйте, Pepel, Вы писали:

P> к слову, мне сдается это вообще обозначение того, что успешное завершение функции отсылки данных в сокет (не важно где мы это завершение ловим) нифига не гарантирует их доставку ?? тоесть шлю я WSASend() (ну либо тупо send()) 200 байт, словил в первом случае на IOCP успешное завершение — это не гарантия, что на той стороне эти данные были получены, так ?


Именно так.
send не ждет, пока данные уйдут на удаленный конец и тот пришлет подтверждение о получении.
send тупо записывает данные в буфер отправки сетевой подсистемы (кстати размер этого буфера настраивается через вызов setsockopt).
Если в буфере отправки недостаточно места, т.е. вы пишете в буфер отправки быстрее, чем сетевая подсистема успевает их отправлять, то тогда send заблокирует (если сокет в соответсвующем режиме).
То же самое и с приемом данных из сети: сетевая подсистема их принимает и складывает в буфер приема, а вы через вызов recv их оттуда забираете.
Re[42]: winsock и порты завершения ввода-вывода
От: Pepel Беларусь  
Дата: 21.04.09 16:05
Оценка:
спасибо !! исчерпывающие ответы
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.