|
|
|
send и recv
|
|||
|---|---|---|---|
|
#18+
Привет всем! У меня есть клиент и сервер. В обоих по 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 сообщения? По идее я могу и на сервере разделить потоки четко на передающий и принимающий. Наверное, это все решит. Но не хотелось бы... И кроме того просто интересно, почему так. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.07.2005, 16:53 |
|
||
|
send и recv
|
|||
|---|---|---|---|
|
#18+
А потому что у тебя ОДИН канал связи между клиентом и сервером. Потоков там может быть сколько угодно, но до тех пор пока подключение одно общее - все пакеты в нем будут идти в одном общем потоке. В общем, самое простое решение этой задачи - клиент делает два подключения к серверу на разные порты или даже на один и тот же, но тогда в первой посылке после подключения клиент устанавливает для канала его статус - канал для запросов от клиента и канал для сообщений клиенту. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.07.2005, 18:13 |
|
||
|
send и recv
|
|||
|---|---|---|---|
|
#18+
Попробуйте поиграться длиной буфера и флагами-статусом. Это наведёт Вас на решение... Из спецификации на TCP (не дословно)... "...TCP не регламентирует немедленную доставку буфера приёма до процесса приёма... Команда PUSH активирует проталкивание данных до процесса приёма на стороне клиента, даже если буффер данных не до конца наполнен..." где то так...смысл надеюсь передал... с уважением (круглый) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.07.2005, 20:29 |
|
||
|
send и recv
|
|||
|---|---|---|---|
|
#18+
Не мог сразу ответить - уезжал. Сейчас попробую оба варианта. Начну с флагов лучше:) И еще сомнения по поводу 2 потоков. Еще не проверенные, но... Допустим, я сделаю 2 канала. Ну так все равно оба потока сервера буду отправлять данные в один поток данных, который предназначен для передачи Server->Client. И тогда будет то же самое. Или все же нет? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.07.2005, 11:58 |
|
||
|
send и recv
|
|||
|---|---|---|---|
|
#18+
Я не уверен, но по моему, нельзя работать с одним и тем сокетом из разных потоков (без синхронизации). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.07.2005, 12:34 |
|
||
|
send и recv
|
|||
|---|---|---|---|
|
#18+
roman10Я не уверен, но по моему, нельзя работать с одним и тем сокетом из разных потоков (без синхронизации). Без какой синхронизации? Можно поподробнее? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.07.2005, 12:49 |
|
||
|
send и recv
|
|||
|---|---|---|---|
|
#18+
TnedutSНачну с флагов лучше:) Какие флаги??? TnedutSИ еще сомнения по поводу 2 потоков. Еще не проверенные, но... Допустим, я сделаю 2 канала. Ну так все равно оба потока сервера буду отправлять данные в один поток данных, который предназначен для передачи Server->Client. И тогда будет то же самое. Или все же нет? Повторяю: Каналов должно быть два! Один для запросов клиента к серверу. Второй для посылок сообщений от сервера к клиенту. Это самое простое решение. Можно сделать все и на одном канале. Но тогда надо делать на сервере/клиенте один процесс принимает/передает данные. Каждый логический пакет данных предваряется описанием какого этот пакет типа и длиной пакета. И процесс непосредственно работающий с сокетом уже отправляет по IPC каналам полученый пакет в нужный процесс. То есть реализовать принцип очереди. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.07.2005, 17:40 |
|
||
|
send и recv
|
|||
|---|---|---|---|
|
#18+
White Owl TnedutSНачну с флагов лучше:) Какие флаги??? TnedutSИ еще сомнения по поводу 2 потоков. Еще не проверенные, но... Допустим, я сделаю 2 канала. Ну так все равно оба потока сервера буду отправлять данные в один поток данных, который предназначен для передачи Server->Client. И тогда будет то же самое. Или все же нет? Повторяю: Каналов должно быть два! Один для запросов клиента к серверу. Второй для посылок сообщений от сервера к клиенту. Это самое простое решение. Можно сделать все и на одном канале. Но тогда надо делать на сервере/клиенте один процесс принимает/передает данные. Каждый логический пакет данных предваряется описанием какого этот пакет типа и длиной пакета. И процесс непосредственно работающий с сокетом уже отправляет по IPC каналам полученый пакет в нужный процесс. То есть реализовать принцип очереди. Все. Наконец-то дошло:) Спасибо. Первый способ мне гораздо больше нравится. Попробую. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.07.2005, 17:57 |
|
||
|
send и recv
|
|||
|---|---|---|---|
|
#18+
а теперь правильный вопрос... точнее совет дня... рекомендую сделать следующее... 1) на приёме сделать ожидание пакета, но длину буфера влепите ноль. Запрос вернёт (поприходу пакета) длину пакета реальную. следующей строкой сделайте выборку функцией ресиив, с указанной длиной. это классика. мать её. удачи вам (круглый) ЗЫ Предпологаю, что данные просто буфферизируються в Вашем буфере. Либо подгоните длину буфера под один пакет. Длину сделайте одинаковую во всех типах пакетов. ЗЫ ЗЫ ик... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.07.2005, 18:54 |
|
||
|
send и recv
|
|||
|---|---|---|---|
|
#18+
кстати по поводу каналов.... 1) TCP протокол обеспечивает соединение поинт-поинт (точка-точка) и гарантирует целостную и упорядочную доставку данных как в одну так и в другую сторону. 2) В нутри протокола существует логика передачи инфы в две стороны. 3) Соединение идентифицируеться такими параметрами как IP адресс (IP уровень) и TCP порт (TCP уровень). 4) Порт предназначен для идентификации различных процессов работающих на данном хосте или маршрутиризаторе. короче говоря, что это я поехал пересказывать протокол то ? старею... гляньте тут лучше... http://www.helloworld.ru/show.php?curraz=50 с уважением (круглый) ЗЫ Кстати спецификации на протокол описывают и протокол с процессами юзающих данный протокол. Гляньте - очень интересные нюансы мона узнать. Под виндами - думаю докопаться до ориджинал так же мона :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.07.2005, 19:03 |
|
||
|
send и recv
|
|||
|---|---|---|---|
|
#18+
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, соответственно, тоже. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.07.2005, 12:35 |
|
||
|
send и recv
|
|||
|---|---|---|---|
|
#18+
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, соответственно, тоже:) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.07.2005, 12:36 |
|
||
|
send и recv
|
|||
|---|---|---|---|
|
#18+
1) По поводу принятия инфы...Если провести следующий тест... а) на передающей стороне посылаем 2 байта и в след 3 байта. б) на приёмной стороне примем (если долго спали) 5 байт. TCP обеспечивает Вам поток, ни о каких пакетах речь и не идёт :) . 2) По поводу принятия длины. Знаете визуально помню - где то код валялся. Не могу найти. Да, в том контексте который юзаете Вы - абсолютно верно. Вернёться нул. Но млин, я когда то так же использовал сОкеты. Потом попалось другое решение - именно в разграничении фаз приёма и наполнении буфера. Хотя если Вы опять проспите - то в следующий раз примете два подряд куска данных. Что не снимает проблему. 3) Выход - либо стандартной длины данные. Либо парсить поток (код-длина). с уважением (круглый) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.07.2005, 16:14 |
|
||
|
send и recv
|
|||
|---|---|---|---|
|
#18+
kolobok01) По поводу принятия инфы...Если провести следующий тест... а) на передающей стороне посылаем 2 байта и в след 3 байта. б) на приёмной стороне примем (если долго спали) 5 байт. TCP обеспечивает Вам поток, ни о каких пакетах речь и не идёт :) . По идее долго спать клиент не должен. Ну буду иметь ввиду. Спасибо. kolobok0 2) По поводу принятия длины. Знаете визуально помню - где то код валялся. Не могу найти. Да, в том контексте который юзаете Вы - абсолютно верно. Вернёться нул. Но млин, я когда то так же использовал сОкеты. Потом попалось другое решение - именно в разграничении фаз приёма и наполнении буфера. Хотя если Вы опять проспите - то в следующий раз примете два подряд куска данных. Что не снимает проблему. 3) Выход - либо стандартной длины данные. Либо парсить поток (код-длина). с уважением (круглый) Буду парсить, т.к. стандартной длины точно не получится. Спасибо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.07.2005, 17:27 |
|
||
|
|

start [/forum/topic.php?fid=57&msg=33160116&tid=2033042]: |
0ms |
get settings: |
11ms |
get forum list: |
18ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
63ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
72ms |
get tp. blocked users: |
1ms |
| others: | 236ms |
| total: | 423ms |

| 0 / 0 |
