Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 2005.12.04;
Скачать: [xml.tar.bz2];

Вниз

Как грамотно работать с сокетами   Найти похожие ветки 

 
Piter ©   (2005-08-19 15:16) [0]

Пишу плагин для программы. С WinApi приходится работать через внутренний API программы, но фактически это реализается блокирующих сокетов.

Вот думаю - как лучше организовать прием/передачу данных.

Допустим, я сделал поток - он принимает данные, в какой-то момент поток "завис" на Receive (данных нету).
А если в это время надо что-то отправить? Делать другой поток?
То есть, прием данных в одном потоке, передача в другом? Или как это грамотно реализовать?


 
Rouse_ ©   (2005-08-19 15:25) [1]

Обязательно блокирующие? А чем select не подходит?


 
Digitman ©   (2005-08-19 15:25) [2]


> фактически это реализается блокирующих сокетов


реализуй на неблокирующих - проблема сама собой отпадет

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

в принципе, насколько мне известно, гнездо как Winsock-объект является thread-safe-объектом, т.е. хэндл одного и того же гнезда после установления соединения можно использовать в разных трансп.тредах (один передает, другой принимает) без крит.секций или иной синхронизации ... но рисковать я бы не стал - лучше и надежней либо работа в неблок.режиме либо в блок.режиме по таймауту


 
Piter ©   (2005-08-19 15:40) [3]

Rouse_ ©   (19.08.05 15:25) [1]
А чем select не подходит?


не понял - а причем здесь он? Он вроде как тоже заблокирует поток на время ожидания подключения, например, после Connect. Как он поможет... я немного не понял :(

Digitman ©   (19.08.05 15:25) [2]
реализуй на неблокирующих


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

Digitman ©   (19.08.05 15:25) [2]
используй таймаут ожидания чтения - по истечению таймаута recv() вернет управление, и ты сможешь в том же трансп.трэде использовать это же гнездо для передачи


да, я об этом думал... Ожидать чтения, после возврата управления отправлять из очереди, потом опять ожидать чтения. А как с производительностью при этом?

Я вот думаю таймаут где-то в 500мс поставить - нормально будет?

И интересно - а как те же онлайновые игры, где пинг по 10мс бывает.. Они на неблокирующих сокетах или у них время "опроса" катастрофически малое?


 
Eraser ©   (2005-08-19 15:41) [4]

Piter ©   (19.08.05 15:16)

В дополнении, как транспортное средство можно использовать уже готовые решения, как mailslots, но тут по обстоятельствам смотреть надо.


 
Digitman ©   (2005-08-19 15:52) [5]


> Piter ©   (19.08.05 15:40) [3]


> чем select не подходит?
>
> не понял - а причем здесь он?


вот там как раз и можно задать таймаут ожидания того или иного свершившегося трансп.события


> учитываются всякие общие настройки, вроде прокси сервера
> и всего такого


какое отношение всякие прокси-серверы имеют к трансп.уровню ?
это уже прикладной уровень, на этом уровне фактический режим работы гнезда совершенно безразличен


> Ожидать чтения, после возврата управления отправлять из
> очереди, потом опять ожидать чтения. А как с производительностью
> при этом?


Гнездовые Инди-объекты по сути так и работают.
И на производительность пока вроде никто не жаловался.

Хотя , думаю, такой подход полностью оправдан лишь при разработке кроссплатформенного кода трансп.уровня.

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


> как те же онлайновые игры, где пинг по 10мс бывает


в мусор такие игры !
зачем, спрашивается, без конца пинговать удаленный хост, если его вдруг возникший отказ можно обнаружить в любой момент обычной операцией send или recv ?


 
Piter ©   (2005-08-19 16:13) [6]

Digitman ©   (19.08.05 15:52) [5]
какое отношение всякие прокси-серверы имеют к трансп.уровню ?


да блин. Объясняю еще раз. Я ведь не WinApi использую, я использую API той программы, для которой пишу плагин.

Я не делаю вызовов WinApi, я делаю вызовы API программы. Я и говорю, что на самом деле там фактически реализованы блокирующие сокеты.
Но не на прямую.
Например, я работаю как бы напрямую с удаленным хостом, но программа, если в ней есть настройки, может пустить это через какой-нибудь Socks прокси. Я даже и не буду знать, что работаю через прокси, а мне это и не надо.

Digitman ©   (19.08.05 15:52) [5]
в мусор такие игры !
зачем, спрашивается, без конца пинговать удаленный хост


кто говорит о постоянной бесполезной пинговке?

Ты когда-нибудь играл в сетевые 3D-Action? Там ведь действие происходит непрерывно, непрерывная передача данных в обе стороны.
Поэтому там конечно не эхо-запрос/ответ, но пинг меряется по ходу дела постоянно.


 
Piter ©   (2005-08-19 16:19) [7]

А, вот еще что забыл.

Так 500мс - это нормально? Или поменьше/побольше надо сделать?


 
Eraser ©   (2005-08-19 16:29) [8]

Piter ©   (19.08.05 16:13) [6]
Поэтому там конечно не эхо-запрос/ответ, но пинг меряется по ходу дела постоянно.


Пинг меряется именно при передачи данных. Под пингом в этом случае подразумевается время отклика на запрос.


 
Digitman ©   (2005-08-19 16:37) [9]


> Piter ©   (19.08.05 16:13) [6]


тогда, скорей всего, ты ограничент только возможностями этого АПИ.

думаю, что бессмысленно пытаться из двух разных потоков по одному и тому же блок.соединению одновременно принимать и передавать данные - удаленный хост у тебя наверняка работает в режиме "запрос-ответ" и поддерживает ли он колбэки - это еще бабушка надвое сказала


> кто говорит о постоянной бесполезной пинговке?

ты говоришь)
или я тебя не понял ..


> где пинг по 10мс бывает


по 10мс это что - период или длительность ?

зачем, спрашивается, нужен icmp, когда сам tcp всегда известит меня об разрыве/отказе коннекта с удал.хостом в момент когда я пытаюсь что-то передать или принять ?


 
Digitman ©   (2005-08-19 16:44) [10]


> пинг меряется


разберись уже в конце-концов в терминологии и протоколах ..

пинг (ping - пакетный Интернет-щуп) есть ничто иное как инф.обмен по протоколу icmp


 
Piter ©   (2005-08-19 17:05) [11]

хм...

Digitman ©   (19.08.05 15:25) [2]
то используй таймаут ожидания чтения - по истечению таймаута recv() вернет управление


а ведь в recv никакого таймаута не задается...


 
Piter ©   (2005-08-19 17:09) [12]

Digitman ©   (19.08.05 16:44) [10]
разберись уже в конце-концов в терминологии и протоколах ..

пинг (ping - пакетный Интернет-щуп) есть ничто иное как инф.обмен по протоколу icmp


я всегда думал иначе :(
Эхо-запрос и эхо-ответ - это обмен по icmp. А понятия Ping в протоколе icmp нету.

Ping - это просто название программы, которая реализовывает эхо-запросы и ответы по протоколу icmp.

Я же под пингом имел более широкое понятие - время дохода пакета от одного хоста к другому. Но так как говорить "время дохода пакета од одного компьютера до другого" слишком долго, то проще - Ping.

ПО-моему, достаточно общепринято:

- Какой у тебя пинг
- У меня 25

Хотя если придраться - то диалог неправильный :)


 
Digitman ©   (2005-08-19 17:24) [13]


> ведь в recv никакого таймаута не задается


пардон, таймаут задается в select()


> время дохода пакета от одного хоста к другому


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

что из того , что ответ на icmp-запрос пришел не через 10 мс (как на предыдущий запрос), а через, скажем, 11 мс ? "задержка" в 1 мс абсолютно ни о чем не говорит


 
Piter ©   (2005-08-19 17:31) [14]

Digitman ©   (19.08.05 17:24) [13]
и какой смысл его измерять ?


практический смысл - Online сервер учитывает задержку при стрельбе, например. Чтобы участники были в более-менее равных ситуациях.

На клиентской стороне время пинга тоже показывается - просто для информации.

Например, вижу, что пинг колеблется в районе 50 - нормально играю.

А если на каком-нибудь сервере вижу пинг около 300 - то там и делать нечего.

Пинг вещь не постоянная, но при обычном коннекте и без всяких ЧП его среднестатическое значение секунд за 5-10 практически не меняется, +-10


 
Piter ©   (2005-08-19 17:35) [15]

Digitman ©   (19.08.05 17:24) [13]
пардон, таймаут задается в select()


да... но я что-то никак логику оформить не могу.

1) Итак, я делаю Connect.

2) делать Recv не имеет смысла, он вернет -1.
 Поэтому логично использовать Select. Но куда handle писать? На чтение, на запись, на исключение?

Допустим, на запись

3) Select отдал управление. А дальше что? Писать? А если нечего писать? Тогда на чтение ставить?

Так и чередовать Select"ы - с чтения на запись?

Не могу строгую логику построить...


 
FireMan_Alexey ©   (2005-08-19 18:32) [16]

>Piter
Тебе говорят, что если ты пишеш под винду, то пользуйся не блок режимом.
Сам когда-то бился головой как прокси написать :)

Вот пример отсюда отталкивайся!

Function GetEvent(Event,FD_XXX:Integer):Boolean;
Begin
 Result:=(Event and FD_XXX)<>0;
End;
...
Event:=WSACreateEvent;
 WSAEventSelect(Socket,Event,FD_READ or FD_WRITE or FD_CLOSE);
 //-------------------
While not Terminated do
Begin
     Index:=WSAWaitForMultipleEvents(1,@Event,False,10{Таймаут},False);
     Case Index Of
       0:Begin
           Error:=WSAEnumNetworkEvents(Socket,Event,@NetEvents);
If GetEvent(NetEvents.lNetworkEvents,FD_READ) Then
             Begin
Recv(...)
End;
If GetEvent(NetEvents.lNetworkEvents,FD_WRITE) Then
Begin
Send(...)
End;
... и т.д.


 
Piter ©   (2005-08-19 18:44) [17]

FireMan_Alexey ©   (19.08.05 18:32) [16]
Тебе говорят, что если ты пишеш под винду, то пользуйся не блок режимом


отправляю еще раз перечитать мои посты [0] и [3]


 
Defunct ©   (2005-08-19 23:31) [18]

> Piter ©  

Выброси API программы к мохнатой бабушке.


 
Piter ©   (2005-08-20 00:11) [19]

Defunct ©   (19.08.05 23:31) [18]

Какие еще советы будут?
Может, Windows удалить?


 
Defunct ©   (2005-08-20 04:41) [20]

Piter ©   (20.08.05 00:11) [19]

Читая ветку, я так понял у тебя есть только одна проблема - привязка к API программы. Если убрать эту привязку (чит. причину) пропадет и проблема (чит. следствие).

Ты с сетью работаешь через программу для которой пишешь плагин? Или плагин предназначен для работы с сетью этой программы. Как-нибудь поясни задачку-то, а то от прочтения сложилось такое впечатление, что ты дурью маешься. Какие-то пинги, таймауты по 500ms, когда в инете может быть и 20000ms, черт-те что. Неблокирующий режим нельзя потому что исп. Socks. Каша какая-то.

Socks вообще никакого влияния на твою программу не окажет. Socks обеспечивает тебе связь на сеансовом уровне.

С другой стороны, если в программе уже есть API для работы с сетью, тогда зачем использовать что-то еще?

Короче если ты пишешь плагин для миранды, а скорее всего именно для нее ты его и пишешь. То твой изначальный вопрос:

"Вот думаю - как лучше организовать прием/передачу данных."

Вообще не к месту, т.к. прием/передача данных в миранде уже реализованы.


 
Piter ©   (2005-08-20 11:59) [21]

Defunct ©   (20.08.05 4:41) [20]
Ты с сетью работаешь через программу для которой пишешь плагин?


да, именно так. Да, пишу плагин для Miranda.

"Вот думаю - как лучше организовать прием/передачу данных."

Вообще не к месту, т.к. прием/передача данных в миранде уже реализованы


да? А ты писал плагины к ней? Фактически там реализованы блокирующие сокеты, о чем я и написал.

Defunct ©   (20.08.05 4:41) [20]
если в программе уже есть API для работы с сетью, тогда зачем использовать что-то еще?


а я и не использую


 
Lamer@fools.ua ©   (2005-08-20 14:57) [22]

>>Piter ©   (19.08.05 17:09) [12]

>пинг (ping - пакетный Интернет-щуп) есть ничто иное как инф.обмен по протоколу icmp

я всегда думал иначе :(
Эхо-запрос и эхо-ответ - это обмен по icmp. А понятия Ping в протоколе icmp нету.

Ping - это просто название программы, которая реализовывает эхо-запросы и ответы по протоколу icmp.

Я же под пингом имел более широкое понятие - время дохода пакета от одного хоста к другому. Но так как говорить "время дохода пакета од одного компьютера до другого" слишком долго, то проще - Ping.


В народе часто говорят ping/пинг, но это неправильно. Правильно latency/задержка.


 
Piter ©   (2005-08-20 17:37) [23]

Lamer@fools.ua ©   (20.08.05 14:57) [22]
В народе часто говорят ping/пинг, но это неправильно


я говорил об этом. Но коли уж приелось...

Дельфи - это тоже неправильно.

И называть компанию Xerox "Ксерокс" - тоже неверно.


 
Lamer@fools.ua ©   (2005-08-20 18:12) [24]

>>Piter ©   (20.08.05 17:37) [23]

>И называть компанию Xerox "Ксерокс" - тоже неверно.

Компанию называть "Ксерокс" как раз правильно, если на то пошло. А аппарат - не "Ксерокс", а "копир".

Насчёт Delphi вообще не понял, что имелось в виду...

P.S. Ладно. Завязываем с оффтопом :-)


 
Piter ©   (2005-08-20 18:57) [25]

Lamer@fools.ua ©   (20.08.05 18:12) [24]

Правильно говорить "Дельфай". Тоже самое и с Xerox.

Но почему-то никто не придирается...


 
Alexander Panov ©   (2005-08-20 19:44) [26]

Piter ©   (20.08.05 18:57) [25]
Правильно говорить "Дельфай".


Неправильно. Правильно Делфи.


 
Piter ©   (2005-08-20 23:20) [27]

Alexander Panov ©   (20.08.05 19:44) [26]
Правильно Делфи


Где, в России? :)


 
Alexander Panov ©   (2005-08-20 23:53) [28]

Где, в России? :)

Уг. именно.


 
Piter ©   (2005-08-21 00:17) [29]

Alexander Panov ©   (20.08.05 23:53) [28]

Так и я о том же.

А на самом то деле - правильно по другому.


 
Lamer@fools.ua ©   (2005-08-21 12:44) [30]

>>Piter ©   (20.08.05 18:57) [25]

>Правильно говорить "Дельфай". Тоже самое и с Xerox.

Если говорить на манер англоязычных пиплов, не учивших историю, то непонятно, откуда взялся мягкий знак. Если же говорить на манер людей хоть немного помнящих историю Древней Греции, то правильно (или по крайней мере общепринято) говорить "Делфи" либо на русский манер "Дельфи".

А насчет Xerox"а - да. Правильно, всё-таки, говорить "Зирокс" (ударение на последнем слоге).



Страницы: 1 вся ветка

Форум: "Сети";
Текущий архив: 2005.12.04;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.54 MB
Время: 0.034 c
2-1132477613
AlexLines
2005-11-20 12:06
2005.12.04
Отчего нет печати


2-1132427524
Avdoshin
2005-11-19 22:12
2005.12.04
файл иконки


2-1132265434
demon_god
2005-11-18 01:10
2005.12.04
Получить координаты точки по удалению и азимуту


5-1114511915
Бывший студент
2005-04-26 14:38
2005.12.04
Свойство предка


6-1124781103
tomkat
2005-08-23 11:11
2005.12.04
Как в INDY SMTP вложить атач ?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский