Правильная обработка сетевых таймаутов в Windows CE - PullRequest
3 голосов
/ 19 мая 2009

Я пытаюсь выполнить относительно простую операцию отправки / получения TCP-сокета в Windows CE с использованием .NET Compact Framework. Я пытаюсь установить значение тайм-аута так, чтобы чтение / запись происходило при медленном тайм-ауте соединения, а не навсегда блокироваться. В полной структуре я могу просто установить свойства ReceiveTimeout и SendTimeout для объекта Socket. К сожалению, установка этих свойств в компактной среде сразу приводит к SocketException при использовании неподдерживаемого параметра сокета.

Пройдя немного дальше, я наткнулся на эту страницу, на которой написано следующее:

    The following table shows BSD options not supported for setsockopt:

    Value            Type       Description
    SO_ACCEPTCONN    BOOL       Sets socket listening.
    SO_RCVLOWAT      int        Sets recv low watermark.
    SO_RCVTIMEO      int        Sets time-out for recv.
    SO_SNDLOWAT      int        Sets send low watermark.
    SO_SNDTIMEO      int        Sets time-out value for send.
    SO_TYPE          int        Sets socket type.

Так что не похоже, что Windows CE поддерживает тайм-ауты. Тайм-аут в конечном итоге произойдет на не отвечающем соединении, но кажется, что он занимает около минуты (должен быть жестко задан где-то в WinCE). Так что теперь я пытаюсь выяснить, как реализовать это вручную. Моя первая мысль - использовать асинхронный ввод-вывод, который позволяет мне WaitOne(timeout). Однако это не остановит асинхронный поток, который будет зависать на EndSend() или EndReceive(). Таким образом, даже если я смогу перевести свой основной поток в тайм-аут, все равно будут оставаться потоки, пока не будет достигнут жестко заданный тайм-аут. В течение этого времени мое приложение не будет корректно закрываться. Единственный способ обойти эту проблему - это прекратить асинхронный поток, но это очень плохая идея, и я бы хотел ее избежать.

Так каков правильный способ справиться с этим? Должен быть простой способ, поскольку у других приложений (например, IE на WinCE), по-видимому, нет проблем с тайм-аутом или отменой ожидающих сетевых операций, и они также могут без проблем завершить работу.

1 Ответ

2 голосов
/ 19 мая 2009

Я нашел чистый способ сделать это. В основном я делаю отправку и получение в отдельном потоке, а затем жду события (должно сработать событие ручного или автоматического сброса). Если время ожидания истекло, то простое закрытие (или удаление) сокета отменяет блокировку чтения / записи в другом потоке, вызывая изящное (исключение выдается при выходе из вызова () / получения () в этом потоке. Надеюсь, это будет полезно для кого-то еще ...

...