powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / send и recv
14 сообщений из 14, страница 1 из 1
send и recv
    #33155303
TnedutS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Привет всем!

У меня есть клиент и сервер.
В обоих по 2 потока.

На клиенте потоки разделены грубо говоря на передающий и принимающий.
На сервере немного не так.
1 поток.
//Принимаем запрос
while((bytes_recv = recv(client_socket,&buff[0],sizeof(buff),0)) > 0)
{
...

case 2:
{

buff[0] = LOGICALREPLY;
//Исполняем функцию
buff[1] =registerSinkAddress(&buff[1]);

semTake(semSend,WAIT_FOREVER);
//логический результат выполнения сразу шлем клиенту
send(client_socket,&buff[0],2,0);
semGive(semSend);

printf("regAddress\n");
break;
}
...
}

И есть у сервера второй поток. Он время от времени шлет некоторые сообщения тому же клиенту.

semTake(semSend,WAIT_FOREVER);
int sendA= send(client_socket,&sendBuff[0],sendLength,0);
printf(" %d\n",sendA);
semGive(semSend);

Проблема в том, что на клиентской стороне сообщения воспринимаются как одно.
То есть как одна дейтаграмма.

while((recvSize=recv(my_sock,&recvBuff[0],
sizeof(recvBuff)-1,0))>0 && isConnect==true)
{
// display
printf("S=>C:%d \n",recvSize);

recvSize получается как сумма длин 2 сообщений - 2 + sendLength!
Поставил даже семафоры - ничего не изменилось.
Почему так?
Ведь вроде как send посылает целую дейтаграмму, а recv целыми же дейтаграммами и читает. Почему объединяются 2 сообщения?

По идее я могу и на сервере разделить потоки четко на передающий и принимающий.
Наверное, это все решит.
Но не хотелось бы...
И кроме того просто интересно, почему так.
...
Рейтинг: 0 / 0
send и recv
    #33155536
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А потому что у тебя ОДИН канал связи между клиентом и сервером. Потоков там может быть сколько угодно, но до тех пор пока подключение одно общее - все пакеты в нем будут идти в одном общем потоке.
В общем, самое простое решение этой задачи - клиент делает два подключения к серверу на разные порты или даже на один и тот же, но тогда в первой посылке после подключения клиент устанавливает для канала его статус - канал для запросов от клиента и канал для сообщений клиенту.
...
Рейтинг: 0 / 0
send и recv
    #33155698
kolobok0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Попробуйте поиграться длиной буфера и флагами-статусом. Это наведёт Вас на решение...

Из спецификации на TCP (не дословно)...
"...TCP не регламентирует немедленную доставку буфера приёма до процесса приёма... Команда PUSH активирует проталкивание данных до процесса приёма на стороне клиента, даже если буффер данных не до конца наполнен..."

где то так...смысл надеюсь передал...

с уважением
(круглый)
...
Рейтинг: 0 / 0
send и recv
    #33159048
TnedutS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Не мог сразу ответить - уезжал.

Сейчас попробую оба варианта.
Начну с флагов лучше:)

И еще сомнения по поводу 2 потоков. Еще не проверенные, но...
Допустим, я сделаю 2 канала. Ну так все равно оба потока сервера буду отправлять данные в один поток данных, который предназначен для передачи Server->Client. И тогда будет то же самое. Или все же нет?
...
Рейтинг: 0 / 0
send и recv
    #33159175
roman10
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я не уверен, но по моему, нельзя работать с одним и тем сокетом из разных потоков (без синхронизации).
...
Рейтинг: 0 / 0
send и recv
    #33159188
TnedutS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
roman10Я не уверен, но по моему, нельзя работать с одним и тем сокетом из разных потоков (без синхронизации).

Без какой синхронизации? Можно поподробнее?
...
Рейтинг: 0 / 0
send и recv
    #33159965
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TnedutSНачну с флагов лучше:)
Какие флаги???

TnedutSИ еще сомнения по поводу 2 потоков. Еще не проверенные, но...
Допустим, я сделаю 2 канала. Ну так все равно оба потока сервера буду отправлять данные в один поток данных, который предназначен для передачи Server->Client. И тогда будет то же самое. Или все же нет?
Повторяю: Каналов должно быть два! Один для запросов клиента к серверу. Второй для посылок сообщений от сервера к клиенту. Это самое простое решение.

Можно сделать все и на одном канале. Но тогда надо делать на сервере/клиенте один процесс принимает/передает данные. Каждый логический пакет данных предваряется описанием какого этот пакет типа и длиной пакета. И процесс непосредственно работающий с сокетом уже отправляет по IPC каналам полученый пакет в нужный процесс. То есть реализовать принцип очереди.
...
Рейтинг: 0 / 0
send и recv
    #33160021
TnedutS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
White Owl TnedutSНачну с флагов лучше:)
Какие флаги???

TnedutSИ еще сомнения по поводу 2 потоков. Еще не проверенные, но...
Допустим, я сделаю 2 канала. Ну так все равно оба потока сервера буду отправлять данные в один поток данных, который предназначен для передачи Server->Client. И тогда будет то же самое. Или все же нет?
Повторяю: Каналов должно быть два! Один для запросов клиента к серверу. Второй для посылок сообщений от сервера к клиенту. Это самое простое решение.

Можно сделать все и на одном канале. Но тогда надо делать на сервере/клиенте один процесс принимает/передает данные. Каждый логический пакет данных предваряется описанием какого этот пакет типа и длиной пакета. И процесс непосредственно работающий с сокетом уже отправляет по IPC каналам полученый пакет в нужный процесс. То есть реализовать принцип очереди.

Все. Наконец-то дошло:)
Спасибо.
Первый способ мне гораздо больше нравится.
Попробую.
...
Рейтинг: 0 / 0
send и recv
    #33160116
kolobok0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а теперь правильный вопрос...
точнее совет дня...
рекомендую сделать следующее...
1) на приёме сделать ожидание пакета, но длину буфера влепите ноль. Запрос вернёт (поприходу пакета) длину пакета реальную. следующей строкой сделайте выборку функцией ресиив, с указанной длиной. это классика. мать её.



удачи вам
(круглый)
ЗЫ
Предпологаю, что данные просто буфферизируються в Вашем буфере. Либо подгоните длину буфера под один пакет. Длину сделайте одинаковую во всех типах пакетов.
ЗЫ ЗЫ
ик...
...
Рейтинг: 0 / 0
send и recv
    #33160129
kolobok0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
кстати по поводу каналов....

1) TCP протокол обеспечивает соединение поинт-поинт (точка-точка) и гарантирует целостную и упорядочную доставку данных как в одну так и в другую сторону.
2) В нутри протокола существует логика передачи инфы в две стороны.
3) Соединение идентифицируеться такими параметрами как IP адресс (IP уровень) и TCP порт (TCP уровень).
4) Порт предназначен для идентификации различных процессов работающих на данном хосте или маршрутиризаторе.

короче говоря, что это я поехал пересказывать протокол то ?
старею...

гляньте тут лучше...

http://www.helloworld.ru/show.php?curraz=50

с уважением
(круглый)
ЗЫ
Кстати спецификации на протокол описывают и протокол с процессами юзающих данный протокол. Гляньте - очень интересные нюансы мона узнать. Под виндами - думаю докопаться до ориджинал так же мона :)
...
Рейтинг: 0 / 0
send и recv
    #33161081
TnedutS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
kolobok01) на приёме сделать ожидание пакета, но длину буфера влепите ноль. Запрос вернёт (поприходу пакета) длину пакета реальную. следующей строкой сделайте выборку функцией ресиив, с указанной длиной. это классика. мать её.


Объясните, пожалуйста, что за ожидание пакета?
Если функцией recv, то здесь:
while((recvSize=recv(my_sock,&recvBuff[0],
/*sizeof(recvBuff)-1*/0,0))>0 && isConnect==true)
{
int recvSize2 = recv(my_sock,&recvBuff[0],recvSize,0);
...
}

recvSize будет равен 0.
И recvSize, соответственно, тоже.
...
Рейтинг: 0 / 0
send и recv
    #33161083
TnedutS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
TnedutS kolobok01) на приёме сделать ожидание пакета, но длину буфера влепите ноль. Запрос вернёт (поприходу пакета) длину пакета реальную. следующей строкой сделайте выборку функцией ресиив, с указанной длиной. это классика. мать её.


Объясните, пожалуйста, что за ожидание пакета?
Если функцией recv, то здесь:
while((recvSize=recv(my_sock,&recvBuff[0],
/*sizeof(recvBuff)-1*/0,0))>0 && isConnect==true)
{
int recvSize2 = recv(my_sock,&recvBuff[0],recvSize,0);
...
}

recvSize будет равен 0.
И recvSize, соответственно, тоже.

И recvSize2, соответственно, тоже:)
...
Рейтинг: 0 / 0
send и recv
    #33161776
kolobok0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1) По поводу принятия инфы...Если провести следующий тест...
а) на передающей стороне посылаем 2 байта и в след 3 байта.
б) на приёмной стороне примем (если долго спали) 5 байт.
TCP обеспечивает Вам поток, ни о каких пакетах речь и не идёт :) .

2) По поводу принятия длины. Знаете визуально помню - где то код валялся. Не могу найти. Да, в том контексте который юзаете Вы - абсолютно верно. Вернёться нул. Но млин, я когда то так же использовал сОкеты. Потом попалось другое решение - именно в разграничении фаз приёма и наполнении буфера. Хотя если Вы опять проспите - то в следующий раз примете два подряд куска данных. Что не снимает проблему.

3) Выход - либо стандартной длины данные. Либо парсить поток (код-длина).


с уважением
(круглый)
...
Рейтинг: 0 / 0
send и recv
    #33162019
TnedutS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
kolobok01) По поводу принятия инфы...Если провести следующий тест...
а) на передающей стороне посылаем 2 байта и в след 3 байта.
б) на приёмной стороне примем (если долго спали) 5 байт.
TCP обеспечивает Вам поток, ни о каких пакетах речь и не идёт :) .


По идее долго спать клиент не должен. Ну буду иметь ввиду. Спасибо.

kolobok0
2) По поводу принятия длины. Знаете визуально помню - где то код валялся. Не могу найти. Да, в том контексте который юзаете Вы - абсолютно верно. Вернёться нул. Но млин, я когда то так же использовал сОкеты. Потом попалось другое решение - именно в разграничении фаз приёма и наполнении буфера. Хотя если Вы опять проспите - то в следующий раз примете два подряд куска данных. Что не снимает проблему.

3) Выход - либо стандартной длины данные. Либо парсить поток (код-длина).


с уважением
(круглый)

Буду парсить, т.к. стандартной длины точно не получится.
Спасибо.
...
Рейтинг: 0 / 0
14 сообщений из 14, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / send и recv
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]