Определение функциональности удалённого сокета

Discussion in 'WASM.NETWORKS' started by s3dworld, Sep 3, 2011.

  1. s3dworld

    s3dworld Сергей

    Blog Posts:
    0
    Joined:
    Mar 16, 2010
    Messages:
    387
    Location:
    Ртищево
    Всем доброго вечера!

    В запасе Windows Sockets 2, есть функция shutdown(), которая позволяет ограничивать функциональность сокета. Она позволяет:

    - запретить сокету принимать данные
    - запретить сокету отправлять данные
    - запретить сокету принимать и отправлять данные

    Предположим что мы вызвали:

    Code (Text):
    1. shutdown(entitySocket,SD_RECEIVE);
    То есть сокет больше не будет принимать данные. Как это скажется на том сокете, который будет отправлять данные этому сокету?

    То есть я вот про что. У каждого сокета есть два внутренних буфера: буфер приёма и буфер отправки. Когда удалённый сокет отказывается от принятия данных выше показанным кодом, то другой сокет всё же будет отправлять данные? Или же у него буфер отправки будет забиваться? Или при отправке функция send() вернёт какой-то код ошибки?

    Собственно какие нюансы будут при отказе сокета отправлять данные?
     
  2. shchetinin

    shchetinin Member

    Blog Posts:
    0
    Joined:
    May 27, 2011
    Messages:
    715
    s3dworld
    Почитай remark секцию
     
  3. s3dworld

    s3dworld Сергей

    Blog Posts:
    0
    Joined:
    Mar 16, 2010
    Messages:
    387
    Location:
    Ртищево
    shchetinin
    Почитал. И не понял ничего.

    Code (Text):
    1. 1. Call WSAEventSelect to register for FD_CLOSE notification.
    2.  
    3. 2. Call shutdown with how=SD_SEND.
    4.  
    5. 3. When FD_CLOSE received, call the recv or WSARecv until the function completes with success and indicates that zero bytes were received. If SOCKET_ERROR is returned, then the graceful disconnect is not possible.
    6.  
    7. 4. Call closesocket.
    Я запрещаю отсылать. На другой сокет приходит сообщение FD_CLOSE. И он хочет считать данные. Если функция завершится успешно или вернёт 0, то соединение типа закрыто? А если SOCKET_ERROR то отключение не выполнено?

    А если я запретил считывать? То что, мне send() слать при FD_CLOSE?

    Объясните, не жалейте 5 минут.
     
  4. djmans

    djmans New Member

    Blog Posts:
    0
    Joined:
    Dec 27, 2006
    Messages:
    312
    MSDN:

    1. http://msdn.microsoft.com/en-us/library/ms738547(v=vs.85).aspx

    2.
    3.
    4.
    Т.е. SD_RECEIVE == "This has no effect on the lower protocol layers", т.е. просто запрещает вам использовать recv() функции.
    А SD_SEND высылает FD_CLOSE., как и SD_BOTH.

    Рекомендую вообще почитать про TCP протокол, чтобы понять, что происходит на уровне ниже, также можно поглядеть исходники какой нить реализации сокетов беркли.

    Что вообще сделать пытаетесь? Вообще принято вызывать shudown(SD_BOTH), closesocket() вместе в конце сессии.
     
  5. s3dworld

    s3dworld Сергей

    Blog Posts:
    0
    Joined:
    Mar 16, 2010
    Messages:
    387
    Location:
    Ртищево
    djmans
    Сетевой движок пишу для работы с TCP протоколом. Почти все нюансы разобрал. Осталось несколько. Вот и хотел ввести поддержку функции shutdown(). Получается, что когда мы закрываем сокет для приёма данных на любой из сторон, то другая сторона про это ничего не узнает. Собственно одна из сторон так и будет высылать пакеты. А если мы отключим сокет для отправки сообщений, то другая сторона получит уведомление FD_CLOSE и тестом через функцию recv() определит закрыто соединение полностью либо другая сторона не хочет больше отправлять нам данные.

    Всё равно как-то это всё размыто. Если нам будет запрещено использовать recv() после вызова shutdown() для отключения приёма данных, будут ли забиваться буфер приёма?

    И ещё вопрос как раз по поводу этих самых буферов. Какой их размер по умолчанию (для буфера приёма и буфера отправки)?

    И что будет, если изменить размер буфера, когда там уже содержались данные? Они сотрутся? Например если установили размер больше чем было? А если меньше чем было?
     
  6. djmans

    djmans New Member

    Blog Posts:
    0
    Joined:
    Dec 27, 2006
    Messages:
    312
    >Если нам будет запрещено использовать recv() после вызова shutdown() для отключения приёма данных, будут ли забиваться буфер приёма?
    хз, это уже не ваши проблемы, но если память не подводит, то пакеты просто будут игнорироваться.

    >И ещё вопрос как раз по поводу этих самых буферов. Какой их размер по умолчанию (для буфера приёма и буфера отправки)?
    getsockopt(SO_RCVBUF/SO_SNDBUF)

    >И что будет, если изменить размер буфера, когда там уже содержались данные? Они сотрутся? Например если установили размер больше чем было? А если меньше чем было?
    хз, зачем менять буфер на ходу? Создали сокет - задали все параметры сразу и все.