Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Сети > Отправка данных через сокет


Автор: RomkaRomka 9.9.2005, 14:49
Добрый день!

Столкнулся с такой проблемой: синхронный сокет в блокирующем режиме, соединение установлено. Отправляю данные (send) - возвращается число байт, которое я посылал. Получается данные отправлены. За ненадобностью следом закрываю сокет (closesocket). Смотрю принимающую сторону - пришло не все. Убираю closesocket - приходит все.

В МСДН грится - The successful completion of a send does not indicate that the data was successfully delivered.

Вопрос в том, как можно отследить что данные РЕАЛЬНО ушли?


Заранее благодарен

С уважением, Роман


Автор: Anatoliy 9.9.2005, 23:04
Дело в том, что может быть не достаточно одного вызова send. Функция send возвращает кол-во переданных байт. Можно сделать, например, так

Код

int sendbytes;
int sendbytes_all = 0;
int n = количество байт, которые хотим отправить

do {
      sendbytes = send(...);
      sendbytes_all += sendbytes;
} while (sendbytes_all < n);

Автор: dmit10 10.9.2005, 13:28
int sendbytes;
int sendbytes_all = 0;
int n = количество байт, которые хотим отправить

do {
sendbytes = send(...);
sendbytes_all += sendbytes;
} while (sendbytes_all < n);

+Попробуй перед closesocket вызывать функцию shutdown.

Автор: RomkaRomka 12.9.2005, 12:14
Добрый день!

Спасибо откликнувшимся.

Оно то понятно, что если за один раз все данные не отправились надо повторять отправку циклом. Только я описал немного другую ситуацию. У меня мои 40 кб вылетают из сокета за один прием, первый же вызов send возвращает число, равное размеру моего буфера. Но потом видать данные застряют в стеке протокола TCP за счет медленного клиента. Send вернул нормальное завершение, я закрываю сокет, а часть моих данных еще реально находится в транспортном буфере. Вот хотелось бы отловить момент когда эти данные уйдут оттуда. При том без всяких там подтверждений с другой стороны, а то это уже получится свой протокол.

С уважением, Роман.

Автор: Coocky 12.9.2005, 12:19
Цитата(RomkaRomka @ 12.9.2005, 12:14)
Но потом видать данные застряют в стеке протокола TCP за счет медленного клиента

Это точно? Откуда такие данные?


Цитата(RomkaRomka @ 12.9.2005, 12:14)
При том без всяких там подтверждений с другой стороны

ИМХО без этого не обойтись..
smile

Автор: Mad 12.9.2005, 14:13
Цитата(Coocky @ 12.9.2005, 11:19)
Цитата
При том без всяких там подтверждений с другой стороны

ИМХО без этого не обойтись..

как вариант, клиент может подтверждать окончание приема закрытием сокета со своей стороны

когда у тебя send() отработал, на сервере садиш сокет на recv(), когда клиент закроет сокет recv() вернет -1
а если наступит тайм-аут то вернет 0

Автор: Coocky 12.9.2005, 14:16
Цитата(Mad @ 12.9.2005, 14:13)
когда у тебя send() отработал, на сервере садиш сокет на recv(), когда клиент закроет сокет recv() вернет -1
а если наступит тайм-аут то вернет 0

Дык
Цитата(Coocky @ 12.9.2005, 12:19)
ИМХО без этого не обойтись..
smile
А он просит

Цитата(RomkaRomka @ 12.9.2005, 12:14)
При том без всяких там подтверждений с другой стороны, а то это уже получится свой протокол.


Автор: RomkaRomka 12.9.2005, 16:33
Цитата(Coocky @ 12.9.2005, 12:19)
Цитата(RomkaRomka @ 12.9.2005, )
Но потом видать данные застряют в стеке протокола TCP за счет медленного клиента

Это точно? Откуда такие данные?


Простая логИкаsmile
Из моего приложения данные ушли (send вернул нормальное завершение), в приемник - пришли не все... В метровом шнурке врядли застрянут... Остается транспортный буфер драйвера tcpip.sys. Это я так думаю...

С уважением, Роман.

Автор: Coocky 12.9.2005, 16:39
Цитата(RomkaRomka @ 12.9.2005, 16:33)
В метровом шнурке врядли застрянут... Остается транспортный буфер драйвера tcpip.sys. Это я так думаю...

На каком типе протокола работаешь?

Добавлено @ 16:46
Я имел ввиду TCP или UDP гнездо создаешь?

Автор: RomkaRomka 12.9.2005, 17:33
Цитата(Coocky @ 12.9.2005, 16:39)

На каком типе протокола работаешь?

Добавлено @ 16:46
Я имел ввиду TCP или UDP гнездо создаешь?


TCP. Синхронные сокеты в блокирующем режиме. Впрочем пробовал и c асинхронными неблокирующими. WSASend возвращает 0, что говорит о успешном выполнении отправки. Закрываю сокет и на клиенте таже ситуация. Пришел не весь буфер.

С уважением, Роман.

Автор: Coocky 12.9.2005, 17:38
Ну не знаю... smile
А неужели так принципиально
Цитата(Coocky @ 12.9.2005, 14:16)
При том без всяких там подтверждений с другой стороны, а то это уже получится свой протокол

smile

Автор: RomkaRomka 12.9.2005, 17:50
Цитата(Coocky @ 12.9.2005, 17:38)
Ну не знаю... smile
А неужели так принципиально
Цитата(Coocky @ 12.9.2005, )
При том без всяких там подтверждений с другой стороны, а то это уже получится свой протокол

smile


Мне нужна простая обертка на сокеты, но работающая так как мне нужно. Да и разобраться хотелось бы, может таки есть выход.

С уважением, Роман.

Автор: Mayk 12.9.2005, 17:53
Может поиграться с опциями сокета? Посмотреть в сторону SO_LINGER например. И смотреть в сторону EWOULDBLOCK в результате closesocket? smile

Автор: Mayk 12.9.2005, 18:11
О! Кажись нашел.
Цитата(http)

Note  To assure that all data is sent and received on a connection, an application should call shutdown before calling closesocket (see Graceful shutdown, linger options, and socket closure for more information). Also note, an FD_CLOSE network event is not posted after closesocket is called.

Автор: RomkaRomka 13.9.2005, 11:28
Цитата(Mayk @ 12.9.2005, 18:11)
О! Кажись нашел.
Цитата(http)

Note  To assure that all data is sent and received on a connection, an application should call shutdown before calling closesocket (see Graceful shutdown, linger options, and socket closure for more information). Also note, an FD_CLOSE network event is not posted after closesocket is called.


Ну, спасиба! Наверное это оно самое. Буду копать дальше.

С уважением, Роман.

Автор: MAX2002 26.11.2005, 13:10
Все очень просто smile отключи алгоритм Найгла(сорри если не правильно написал) для данного сокета копай в сторону setsockopt

Автор: Гость_En_t_end 27.11.2005, 14:34
RomkaRomka
Тут рядом в этой ветке тема лежала про концепцию класса-враппера под сокеты, там мне люди очень сильно помогли, думаю их опыт и довольно рациональные решения будут тебе кстати...

Автор: oleg200095 25.3.2010, 13:37
Один дурацкий вопрос.
Как с помощью write отправить через сокет что нибудь кроме строки например число?

Автор: SVN74 17.4.2010, 14:25
Цитата(oleg200095 @  25.3.2010,  13:37 Найти цитируемый пост)
Как с помощью write отправить через сокет что нибудь кроме строки например число?


int A = 5;
 
  write(  (char*)&A  )

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)