Чтение частично от розетки -- sockets поле с участием udp пол Связанный проблема

reading partially from sockets


9
vote

проблема

русский

У меня есть небольшая тестовая программа, которая отправляет много пакетов UDP между Client- & GT; Client (тест Ping / Pong). Пакеты являются фиксированными размерами на каждом запуске (последний запуск максимальный допустимый размер пакета UDP) Я заполняю пакеты случайными данными, за исключением начала каждого пакета, который содержит номер пакета. Поэтому мне интересно только посмотреть, получите ли я все пакеты обратно на клиента.

Я использую sendTo () и recvfrom (), и я только прочитал sizeof (packet_number) (который в этом случае - int). Что происходит с остальными данными? Это заканчивается в сказке (отбрасывается)? Или новый пакет, который приезжает прилагается к этому «старым» данным?

(с помощью Linux)

Английский оригинал

I'm having a little test program that sends a lot of udp packets between client->server->client (ping/pong test). The packets are fixed size on each run(last run is max allowable size of udp packet) I'm filling the packets with random data except for the beginning of each packet that contains the packet number. So I'm only interested to see if I receive all the packets back at the client.

I'm using sendto() and recvfrom() and I only read the sizeof(packet_number) (which in this case is an int). What happens to the rest of the data? Does it end up in fairyland (gets discarded)? or does the new packet that arrives gets appended to this "old" data?

(using linux)

</div
     

Список ответов

14
 
vote
vote
Лучший ответ
 

Каждый читал из разъема UDP de-очереди Один целый datagram выкл. Буфер сокета ядра Независимо от того, какой ваш размер буфера пользователя. То есть:

    .
  • Если ваш буфер больше, чем следующая ожидающая datagram, вы прочитаете меньше, чем размер буфера.
  • Если ваш буфер меньше, вы будете читать ваш размер буфера, а остальные данные отбрасываются.
  • Вы можете установить <код> MSG_TRUNC опция в <код> flags , поэтому <Код> recv(2) вернет всю длину дейтаграмма, а не только часть, которую вы читаете в свой буфер пользователя.

Надеюсь, это поможет.

 

Each read from UDP socket de-queues one whole datagram off kernel socket receive buffer no matter what's your userland buffer size. That is:

  • If your buffer is bigger then the next pending datagram, you'll read less then your buffer size.
  • If your buffer is smaller, you'll read your buffer size worth and the rest of the data is discarded.
  • You can set MSG_TRUNC option in the flags, so recv(2) will return the whole datagram length, not just the part you read into your userland buffer.

Hope this helps.

</div
 
 
5
 
vote

Ответьте на ваш первый вопрос, данные выброшены? Да. IP & AMP; Протоколы ARP входят в игру, когда ваш пакет больше, чем путь MTU. Путь MTU - это максимальная блока передачи пути между вашим клиентом и сервером. Предполагая, что ваша карта Nic является стандартной картой Ethernet, то ваш максимальный MTU составляет 1500. Теперь, позволяет предположить, что весь путь MTU между вашим клиентом и сервером составляет 1500. В этом сценарии, если вы отправите любой пакет, который больше 1472 байтов (1500 - (20 байтового IP-заголовка) - (8 байт UDP заголовка)), затем произойдет фрагментация IP. Это произойдет, так это то, что IP-слой нарежет пакет на фрагменты для удовлетворения MTU ссылки Ethernet. Теперь, прежде чем какие-либо данные могут быть отправлены, MAC-адрес назначения должен быть разрешен. Таким образом, вдруг протокол ARP получит несколько фрагментов IP-адресов IP, запрашивая той же IP-адреса для разрешения адресов MAC. Это произойдет, так это то, что ARP будет начать запрос ARP для первого полученного пакета и дождаться ответа ARP. Во время ожидания ARP будет отказаться от всех фрагментов, делающих тот же запрос ARP и очередь только в очередь, только последний прибывший фрагмент. Следовательно, если вы отправите пакет более 1472 байта, не ожидайте получить весь пакет на другом конце, если ваш кеш ARP пуст.

прилагается ли вновь прибывший пакет, чтобы Нет, это не прилагается. UDP - это дейтаграммный протокол со строгими границами сообщений. Следовательно, каждый пакет прибытия считается полной самоопределенной дейтаграммой; Данные не будут добавляться.

 

To answer your first question, does the data get discarded? Yes it does. The IP & ARP protocols come into play when your packet is larger than the Path MTU. The Path MTU is the maximum transmission unit of the path between your client and server. Assuming that your NIC card is a standard ethernet card, then your maximum MTU is 1500. Now, lets assume that the whole Path MTU between your client and server is 1500. In this scenario, if you send any packet that is greater than 1472 bytes (1500 - (20 byte ip header) - (8 byte UDP header)) then IP fragmentation will occur. What will then happen is that the IP layer will chop the packet into fragments to meet the MTU of the ethernet link. Now, before any data can be sent, the MAC address of the destination needs to be resolved. So all of a sudden, the ARP protocol will receive multiple IP fragments requesting the same IP to MAC address resolution. What will then happen is that ARP will initiate an ARP request for the first received packet and wait for the ARP response. While waiting, ARP will discard all of the fragments making the same ARP request and queue only the latest arrived fragment. Therefore, if you send a packet greater than 1472 bytes, don't expect to receive the whole packet on the other end if your ARP cache is empty.

Does the newly arrived packet get appended to No, it doesn't get appended. UDP is a datagram protocol with strict message boundaries. Therefore, each arriving packet is considered as a complete self-contained datagram; the data will not get appended.

</div
 
 
     
     
3
 
vote

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

Есть два способа обнаружения усечения:

Используйте <код> MSG_TRUNC флаг. <Код> recvfrom затем вернет истинный размер пакета, даже если он не поместил предоставляемый буфер. Таким образом, вы можете просто проверить, если возвращаемое значение больше, чем <код> len вы дали в качестве аргумента.

Используйте <Код> recvmsg и проверьте возвращенную структуру для <код> TextView0 flag.

Чтобы избежать трактации, используйте 64 k буфера. Пакеты UDP не могут быть больше этого (16-битная длина поле в протоколе).

 

I haven't tested this, but from my interpretation of the man page, it will always be discarded. This seems reasonable since otherwise there would be no way to detect the beginning of the next package.

There are two ways to detect truncation:

Use the MSG_TRUNC flag. recvfrom will then return the true size of the package even if it didn't fit the provided buffer. So you can simply check if the return value is larger then the len you gave as an argument.

Use recvmsg and check the returned structure for the MSG_TRUNC flag.

To avoid trunaction, use a 64k buffer. UDP packages can't be bigger than that (16 bit length field in the protocol).

</div
 
 

Связанный проблема

72  Розетка принимает - «Слишком много открытых файлов»  ( Socket accept too many open files ) 
Я работаю над школьным проектом, где мне пришлось написать многопоточный сервер, и теперь я сравниваю его с Apache, запустив некоторые тесты против него. Я ис...

22  Сокет с использованием в качании апплета  ( Socket using in a swing applet ) 
Я должен сделать сервер и AMP; Клиент в Java, основанный на качании и GUI.I, чтобы сделать как-то розетку, которое будет переходить с сервера к клиенту и от к...

0  Java Charbuffer от Socket Error_format  ( Java charbuffer from socket error format ) 
Java: 1.7 ОС: Linux (но я не знаю, какой это Linux) У меня есть шарбафер, чтобы сдержать что-то, что я читал из буферреатора сокета. Гнездо было установлено...

0  Ответить на конкретный клиент сокета  ( Reply to specific socket client ) 
Я использую C #. У меня есть один сервер сокета в PC A и трех клиентах сокета на ПК B, PC C, и PC D. Когда PC A получает данные, я хочу отправить эти данны...

0  Разъем ввода не возвращается -1 в конце потока  ( Socket inputstream doesnt return 1 at the end of stream ) 
Это фрагмент кода, где происходит проблема: <код> public static byte[] copyLargeExt(InputStream input) throws IOException { ByteArrayOutputStream ba...

0  Как получить доступ к тому же сокету на нескольких потоках для многопоточного клиента  ( How to access same socket on multiple threads for multi threaded client ) 
У меня есть многопоточный клиент, который настроен для получения сообщений на одном потоке с сервера, в то время как другой поток ждет для ввода пользователя,...

2  Опубликовать большие файлы в Android на сервер  ( Post large files in android to server ) 
Мне нужно отправлять большие файлы более 10 МБ на сервер из приложения Android. Это дает мне <код> ThisWorkbook.Sheets(Array("Sheet1", "Sheet2", "Sheet3")).Se...

1  Получение нескольких сообщений через SocketServer, но один отправлен  ( Receiving multiple messages via socketserver but one is sent ) 
У a есть приложение с двумя потоками. Его игра с контролируемой сетью, 1. Тема (сервер) . Принимайте сокетные соединения и получать сообщения Когда со...

0  Разъем - Реализация системы очереди в Java  ( Socket queue system design implementation in java ) 
Я работаю в ядре системы прямо сейчас, но я проектирую так, как я собираюсь получить информацию, ниже фактов: Система получит 8000000 транзакций в день в н...

10  Вопрос о Сервере Гнездовой Модель программирования [Закрыто]  ( Question about server socket programming model ) 
<в сторону CLASS = "S-NEWACTS S-WELTIVE__info JS-Post-New Imide MB16« Роль = «Статус»> закрыт. Этот вопрос не соответствует Рекомендациям переполнения ...

5  Как я могу заставить гнездо открыть с Python, чтобы закрыть?  ( How can i force socket opened with python to close ) 
Я в настоящее время использую эту lib для стресса, тестируйте kafka Server, который я настроил: https: // github .com / dsully / pykafka <код> import kafk...

0  Не могу отправить UDP пакет в Qt  ( Can not send udp packet in qt ) 
Все Я хочу использовать Qudpsocket, чтобы отправить пакет UDP, чтобы получить параметр конфигурации с конкретного сервера, но оно не удалось, и я не могу за...

1  .NET Socket Connect IPv6 Ошибка  ( Net socket connect ipv6 error ) 
Я начал получать ошибку после установки нового сетевого адаптера (хотя он отключен) в ранее рабочем коде: <код> Dim MyipAddress As IPAddress Dim M...

193  В чем разница между соединением и прочитанной тайм-аутом для розеток?  ( What is the difference between connection and read timeout for sockets ) 
3 Вопросы: Какая разница между соединением и read timeout для розеток? Что означает соединение тайм-аут в "Infinity" означает? В какой ситуации ...

4  Нарушение песочницы на второй розетке Отправить  ( Sandbox violation on second socket send ) 
У меня есть клиент Flex, используя розетку двоичного двоика (TCP) для связи с сервером Java. У меня есть сервер localhost (Apache), предоставляющий файл cross...