|
|
|
Загадка про сокеты и NIO.
|
|||
|---|---|---|---|
|
#18+
День добрый! Играюсь с сокетами и NIO. Написал следующее: NIO клиент соединяется с NIO сервером и последний начинает слать на клиента данные. Однако скорость отсылки сервером БОЛЬШЕ скорости считывания клиентом: к примеру сервер шлет 1000 байт, а потом спит секунду, а клиент читает 1000 байт, а потом спит 3 секунды. Рано или поздно сервер перестает слать данные непрерывно и начинает жда пока клиент их считает. Засекаю сколько байт было отослано и сколько считано. Между этими двумя цифрами ЕСТЬ РАЗНИЦА. На моем компе эта разница всегда около 28000 байт. Вопрос: где эта разница хранится? Логично предположить, что в буферах сокетов. Однако getSendBufferSize() на сервере и getReceiveBufferSize() на клиенте выдают по 8192. До 28000 не хватает. Замечу также, что если написать аналогичный setup на простых сокетах, то все будет точно так же, однако разница будет составлять всегда 8000 байт, что хотя бы соответствует размеру getReceiveBufferSize() клиента, а точно такой же размер getSendBufferSize() получается не учитывается. Поясните магию, пожалуйста. ps Windows, клиент и сервер на одной машине, соединение через 127.0.0.1. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.11.2013, 10:40:35 |
|
||
|
Загадка про сокеты и NIO.
|
|||
|---|---|---|---|
|
#18+
Dymytry, скорей всего, облажались с подсчетом байтиков, и разницы нет. Хотя без кода так никто вам не скажет точно. еще лучше распечатать сколько отправлено и сколько принято на каждой итерации, тогда можно что-то понять. поток можно "мерять" сниффером типа wireshark, у него там есть follow tcp stream, где можно посмотреть сырые данные, которые бегают. только под виндой wireshark не увидит трафик через 127.0.0.1. Ставье линукс или гоняйте данные по сети. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.11.2013, 15:59:48 |
|
||
|
Загадка про сокеты и NIO.
|
|||
|---|---|---|---|
|
#18+
DymytryЛогично предположить, что в буферах сокетовНифига не логично. Над IP-стеком есть JVM со своими представлениями о прекрасном. Имеет полное право копить данные до считывания приложением, предоставив IP-стеку место для их размещения. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.11.2013, 17:17:36 |
|
||
|
Загадка про сокеты и NIO.
|
|||
|---|---|---|---|
|
#18+
Dymytry Я вспоминаю жлобские времена интернетов с помегабайтной оплатой. Провайдеры считали трафик по разным формулам. Кто-то учитывал входящий. Кто-то входящий и исходящий вместе. Кто-то в совокупности с IPCMP-пакетами или IP. Но это лирика... Дело в том что "байты" не являются единицей учёта трафика в сетях. Там оперируют более крупными вагончиками и тележками. Что ты считал и "засекал" - непонятно. По хорошему ты должен был воспользоваться сетевыми утилитами iptraf или tcpdump. Они выдают реальную картину происходящего. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.11.2013, 19:38:01 |
|
||
|
Загадка про сокеты и NIO.
|
|||
|---|---|---|---|
|
#18+
Вот мой пионерский код. Вроде все линейно, но может я где-то не прав?.. Клиент, который читает раз в секунду: Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. Сервер, который пишет без задержек: Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. Output: автор286000 bytes written. 287000 bytes written. 288000 bytes written. 289000 bytes written. 290000 bytes written. 291000 bytes written. ... has read 253000 has read 254000 has read 255000 has read 256000 has read 257000 has read 258000 has read 259000 has read 260000 has read 261000 has read 262000 Вопрос в том где хранится разница. Базиль, то есть оно может хранится в JVM? А как это понять, что посмотреть, потрогать, почитать? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.11.2013, 00:29:06 |
|
||
|
Загадка про сокеты и NIO.
|
|||
|---|---|---|---|
|
#18+
(случайно стер вместе c комментами строчку buffer.put(data), но она есть :), а редактировать посты тут нельзя что ли.. ) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.11.2013, 00:34:25 |
|
||
|
Загадка про сокеты и NIO.
|
|||
|---|---|---|---|
|
#18+
Dymytry(случайно стер вместе c комментами строчку buffer.put(data), но она есть :), а редактировать посты тут нельзя что ли.. ) Выкладывай правильный сорс еще раз. И импорты добавь. Не ленись. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.11.2013, 01:10:15 |
|
||
|
Загадка про сокеты и NIO.
|
|||
|---|---|---|---|
|
#18+
Ну ок, вот еще раз сервер целиком: Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. Клиент: Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.11.2013, 09:57:45 |
|
||
|
Загадка про сокеты и NIO.
|
|||
|---|---|---|---|
|
#18+
а где тут распечатываются размеры буферов приема-отправки? сделайте так: System.out.println("rcv size ="+ client.getOption(StandardSocketOptions.SO_RCVBUF) ); System.out.println("snd size ="+ client.getOption(StandardSocketOptions.SO_SNDBUF) ); на клиенте распечатайте прием, на сервере - отправку. И когда будут известны эти величины, уже дальше будем думать. на моем компе сервер пишет snd size =331875 при этом за раз при подключении в сокет улетает 1018000 при этом клиент пишет rcv size =131003 Действительно, есть разница. При этом cat /proc/sys/net/ipv4/tcp_wmem выдает 4096 16384 4194304 Получается, что над внутреним буфером сетевухи есть буфер ОС, над которым, насколько понимаю, буфер жабы. Получается, что так. Получается, что у неблокирующих сокетов нету zero-copy политики. Да, действительно печально. Чтобы отправить данные, их надо сначала положить в ByteBuffer, откуда они копируются в буфер ОС, откуда они уходят в буфер сетевой карты. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.11.2013, 20:53:03 |
|
||
|
Загадка про сокеты и NIO.
|
|||
|---|---|---|---|
|
#18+
У меня Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.11.2013, 23:38:07 |
|
||
|
Загадка про сокеты и NIO.
|
|||
|---|---|---|---|
|
#18+
Посмотри исходные коды Netty. В презентации http://www.slideshare.net/danbim/zerocopy-eventdriven-servers-with-netty уверяют что один ByteBuffer из описанной выше цепочки - лишний. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.11.2013, 23:50:02 |
|
||
|
Загадка про сокеты и NIO.
|
|||
|---|---|---|---|
|
#18+
chabapok , у меня 6я Джава и такого метода еще нет, использую client.socket().getSendBufferSize(), который внутри есть Object o = getImpl().getOption(SocketOptions.SO_SNDBUF), думаю это одно и то же. Буферы равны 8192 на прием и на отсылку, а таинственная разница между отправленным и принятым - в районе 27000, Windows 7. Не знаю, есть ли какой-то буфер в самой JVM. Но есть буфер сокета и буфер сетевой карты. Может, помимо буфера сокета есть еще какой-то буфер от ОС. Может, данная разница таится в буфере сетевой карты. Не знаю как его узнать. Вообще непонятно где копать инфу по таким задачкам "на стыке". Книжку бы какую кто посоветовал. mayton , так разница между отправленным и полученным такая же должна быть - в 27000? Adva , спасибо за наводку! правда у меня вряд ли тут случай zero-copy, потому что я не считываю ничего с диска, и мои данные в любом случае идут из Application (это просто массив который я создаю кодом). Но тема интересная, ага. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.11.2013, 13:23:43 |
|
||
|
Загадка про сокеты и NIO.
|
|||
|---|---|---|---|
|
#18+
Dymytry, По сетевым инфу ищут так - гуглят марку сетевой, или то что написано на микросхеме сетевухи. У вас 6 жаба? Некрожабер. У меня убунту, тоже как видите есть разница. Так что все ок, вроде бы. Это особенность протокола - при заполнении буферов tcp отвечает нулевым размером окна и передающая сторона приостанавливает передачу, поэтому нельзя надеяться, что будет иначе. В противовес такой организации существует такая штука как "пить из пожарного крана". Когда передающая сторона просто шлет данные, а если прием не успевает - это его проблемы. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.11.2013, 23:47:31 |
|
||
|
Загадка про сокеты и NIO.
|
|||
|---|---|---|---|
|
#18+
Adva, ясно что лишний Я посмотрел исходники netty, в нем нету либ нативных. Значит, у него сокеты из nio, и его сокеты - надстройка над nio. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.11.2013, 02:21:27 |
|
||
|
Загадка про сокеты и NIO.
|
|||
|---|---|---|---|
|
#18+
Хм... И на coderanch успел вопрос задать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.11.2013, 02:44:32 |
|
||
|
Загадка про сокеты и NIO.
|
|||
|---|---|---|---|
|
#18+
chabapok, а вы уверены что сетевая карта вообще учавствует в этом процессе? это же Loopback. мне кажется, нет. короче, где-то есть какие-то буферы :) mayton, я и на stackoverflow спросил, мне не жалко. однако ж подробнооо ответа никто не знает. нужно читать про устройство JVM, наверное, не знаю что именно. а coderanch слабоватый форум. интересно, какой форум по Джаве самый сильный? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.11.2013, 16:19:53 |
|
||
|
Загадка про сокеты и NIO.
|
|||
|---|---|---|---|
|
#18+
chabapokПолучается, что у неблокирующих сокетов нету zero-copy политикиНифига не получается. Читал, в своё время, документацию по 4.1 версии IP-стека OS/2. Один из разделов объяснял, как предоставить ядру буферы пользовательского кода. Как раз для исключения копирования. В Java, где пользовательский код вообще не может управлять механизмом выделения памяти, страдать об отсутствии zero-copy, как минимум, странно. При наличии Byte- и DirectBuffer - странно вдвойне. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.11.2013, 16:44:15 |
|
||
|
Загадка про сокеты и NIO.
|
|||
|---|---|---|---|
|
#18+
Dymytrymayton, я и на stackoverflow спросил, мне не жалко. однако ж подробнооо ответа никто не знает. нужно читать про устройство JVM, наверное, не знаю что именно. а coderanch слабоватый форум. интересно, какой форум по Джаве самый сильный? Откуда ты брал код Sever ? Сам написал или скопипастил? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.11.2013, 16:51:57 |
|
||
|
Загадка про сокеты и NIO.
|
|||
|---|---|---|---|
|
#18+
ubuntu 12.04 Ставлю в представленном выше коде различные значения SO_RCVBUF и количество отправленных сервером данных меняется в соответстующую сторону. Вполне закономерный результат. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.11.2013, 17:42:48 |
|
||
|
Загадка про сокеты и NIO.
|
|||
|---|---|---|---|
|
#18+
Basil A. Sidorov, ну, и lwip тот же умеет. Но только как это все соотносится с java? Так direct-буфер, если бы был таким уж прямым, то разницы про которую пишет тс не было б. Делаешь write - данные или сразу уходят в буфер сетевой, или возвращается 0. А разница есть. Или я что-то плохо понимаю. Вечером попробую чесную пересылку, между двумя компами, без всяких там loopback-ов. Действительно, этот loopback не пойми как работает, может быть дело в нем. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.11.2013, 19:15:20 |
|
||
|
Загадка про сокеты и NIO.
|
|||
|---|---|---|---|
|
#18+
chabapokНо только как это все соотносится с java?Есть буфер и лежащий в его основе машинный указатель. Машинный указатель не доступен на уровне прикладного кода, но, в любом случае, есть два способа поместить в буфер новые данные: 1. Скопировать данные, не изменяя машинный указатель; 2. Изменить машинный указатель, не копируя данные. Способы можно комбинировать. Вы готовы положить член на отруб, что точно знаете, как именно работает JVM+библиотека классов+нативные методы? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.11.2013, 18:47:08 |
|
||
|
|

start [/forum/topic.php?fid=59&msg=38475193&tid=2128114]: |
0ms |
get settings: |
8ms |
get forum list: |
15ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
200ms |
get topic data: |
6ms |
get forum data: |
1ms |
get page messages: |
32ms |
get tp. blocked users: |
1ms |
| others: | 237ms |
| total: | 508ms |

| 0 / 0 |
