LINUX.ORG.RU

корректная работа с сокетами


0

0

Здравствуйте. Как правильно работать с сокетами - послать данные (проверить что все ушли по возвращаемому значению send() или write()), и сразу ждать ответа (вызвать recv() или read()), или вызвать poll() - получить добро что сокет готов к отправке - и послать, затем так же через poll() узнать, что можно читать - и вызывать read() ? Сделал первый вариант - не везде все проходит гладко, иногда recv() выходит по таймауту (устанавливаю через setsockopt()), и как то данные бывает в разнобой идут (предыдущий тред про сокеты - мой). Буду благодарен совету :)

anonymous

Чтоб не заморачиваться на очередность отправки/принятия сообщений я использовал два сокета. Один на прием, другой на передачу. Еще потом это все хозяйство разбить на потоки. ИМХО непрограммера.

larikin
()

1. Следует уточнять, что используешь TCP (SOCK_STREAM)
2. TCP обеспечивает приход данных в точности в том порядке, в котором
они отправлялись
3. Работать с TCP просто - send (), recv () - больше ничего не нужно
4. poll () нужен, когда ты ожидаешь данные сразу на несколько сокетов,
чтобы не создавать много нитей процессов (потоков, тредов), по одной
на каждый сокет. У тебя, как я понял, один сокет, поэтому не стоит даже тратить время на man poll
5. (самое главное) Когда работаешь с TCP, нужно понимать, что данные
идут потоком и в пути произвольно разбиваются на пакеты и
фрагментируются. То есть если ты выполнял send (условно обозначу) в
таком порядке:
send ("123");
send ("456");
send ("789");
..то на другом конце можешь получить, например, такую
последовательность:
recv () -> "12"
recv () -> "2456"
recv () -> "7"
recv () -> "89"
Это нужно принимать как должное: такой ход нормален, и бороться с
ним не нужно. Начинающим перефрагментация часто не нравится, и каждому
приходится проделать определённый объём уственной работы, чтобы
понять, почему это правильно.

Если ты всем этим уже проникся, то опиши проблему более подробно.. и
лучше не отвлекаться на вольные сочинения про poll и т. п. - куда-то
тебя не туда понесло

erDiZz
()
Ответ на: комментарий от erDiZz

Ок, общаюсь с сервером передавая и получая строки, котрые заканчитваются (всегда) символом новой строки. Для этого написиал функция приема данных - читает побайтова с помощью read() из сокета до тех пор, пока не найдет символ новой строки. Отправляю данные просто функцией write() (или send()). Сам процесс: При конекте сервер посалает строку - читаю ее своей функцией - все ок, все быстро (меньше секунды). Пишу ответ - посылаю данные. write() (send()) говорят, что ушло все. ТОже быстро ушло, строки не большие. Жду ответа от сервера - вызываю свою функцию. read() блокируется (не получает ни байта) и выходит по таймауту (setsockopt() ). Скажу на будущее - если его вызвать снова, то будет то же самое. По идее дальше работать уже смысла нету, но если эту ошибку проигнорить, и послать следующую строку - после вызова функции получения ответа от сервера возвращается ответ на предыдущий запрос (т.е. тот ответ, который мы так долго ждали). Где я что сделал не так ?

anonymous
()
Ответ на: комментарий от erDiZz

  Ок, общаюсь с сервером передавая и получая строки, котрые 
заканчитваются (всегда) символом новой строки. Для этого написиал 
функция приема данных - читает побайтова с помощью read() из сокета до 
тех пор, пока не найдет символ новой строки. Отправляю данные просто 
функцией write() (или send()).

  Сам процесс:
При конекте сервер посалает строку - читаю ее своей функцией - все ок,
все быстро (меньше секунды).
Пишу ответ - посылаю данные. write() (send()) говорят, что ушло все. 
ТОже быстро ушло, строки не большие.
Жду ответа от сервера - вызываю свою функцию. read() блокируется (не 
получает ни байта) и выходит по таймауту (setsockopt() ). Скажу на 
будущее - если его вызвать снова, то будет то же самое.
  По идее дальше работать уже смысла нету, но если эту ошибку 
проигнорить, и послать следующую строку - после вызова функции получения
ответа от сервера возвращается ответ на предыдущий запрос (т.е. тот 
ответ, который мы так долго ждали).
  Где я что сделал не так ?

anonymous
()
Ответ на: комментарий от anonymous

Да, вы правы, чудес не бывает и tcp не так сложен. Ошибка была в строке, которая отправлялась серверу и на которую ожидался ответ :( Извините за пустую трату времени.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.