Сейчас на форуме: hgdagon, asfa (+4 невидимых)

 eXeL@B —› Программирование —› Рушится при Recv в нете но не локалке
. 1 . 2 . >>
Посл.ответ Сообщение


Ранг: 673.3 (! !), 400thx
Активность: 0.40.31
Статус: Участник
CyberMonk

Создано: 25 апреля 2007 22:05 · Поправил: mak
· Личное сообщение · #1

Есть код описанны ниже, это код клиента ....сервер шлет много данных которые потом раскладываются по листвью .... каждые 1024 это название + 4 параметра разделеные символами ...и которые после получения расфасовываются по буферам для вставки ..... если поставить перед ресивом месадж бокс ....то будет много месаг ....тоесть есть многопотоковость ....я как то об этом раньше не думал .... получается если данные шлются на локалке ...это код принимает и все ок .....но если в нете ...то тогда клиент рушится ... с ошибкой в области этого кода .....теперь вопрос ......что делать ....как сделать очередь чтоб все по очереди проходили ..или клиент рушится из за ошибки в этом коде ??? Я так подумал что все потоки с одним буфером работают (с одними точнее) и из за этого все рушится ..вот ..Пасиб заранее


.ELSEIF ax == FD_READ
invoke recv,sock,addr COMANDAIN,1024,0;sizeof COMANDAIN,0

invoke lstrlen ,addr COMANDAIN
mov ecx,eax
lea esi,offset [COMANDAIN]
lea edi,offset [PARAM1IN]
cld
XY: cmp byte ptr [esi],"]"
jz DALEE
movs byte ptr es:[edi],ds:[esi]
jmp XX
DALEE:
cmp byte ptr [esi+1],"["
jz DALEE2
movs byte ptr es:[edi],ds:[esi]
XX:
loop XY
jmp FIRST
DALEE2:

;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
inc esi
inc esi
dec ecx
dec ecx
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
lea edi,offset [PARAM2IN]
cld
XYY: cmp byte ptr [esi],"]"
jz DAALEE
movs byte ptr es:[edi],ds:[esi]
jmp XXX
DAALEE:
cmp byte ptr [esi+1],"["
jz DALEE3
movs byte ptr es:[edi],ds:[esi]
XXX:
loop XYY
jmp FIRST
DALEE3:
; invoke SendMessage,hPROGRESS,PBM_STEPIT,0,0
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
inc esi
inc esi
dec ecx
dec ecx
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
lea edi,offset [PARAM3IN]
cld
XYYY: cmp byte ptr [esi],"]"
jz DAALEEE
movs byte ptr es:[edi],ds:[esi]
jmp XXXX
DAALEEE:
cmp byte ptr [esi+1],"["
jz DALEE4
movs byte ptr es:[edi],ds:[esi]
XXXX:
loop XYYY
jmp FIRST
DALEE4:

;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
inc esi
inc esi
dec ecx
dec ecx
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
lea edi,offset [PARAM4IN]
cld
XYYYYY: cmp byte ptr [esi],"]"
jz DAALEEEE
movs byte ptr es:[edi],ds:[esi]
jmp XXXXX
DAALEEEE:
cmp byte ptr [esi+1],"["
jz DALEE5
movs byte ptr es:[edi],ds:[esi]
XXXXX:
loop XYYYYY
jmp FIRST
DALEE5:

;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
inc esi
inc esi
dec ecx
dec ecx
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
lea edi,offset [PARAM5IN]
cld
X5: cmp byte ptr [esi],"]"
jz DAALE51
movs byte ptr es:[edi],ds:[esi]
jmp XXXXXY
DAALE51:
cmp byte ptr [esi+1],"["
jz FIRST
movs byte ptr es:[edi],ds:[esi]
XXXXXY:
loop X5
;####################################################
FIRST:


вставка в листвью..но тут вроде сто раз проверено все ок
listV PROC
invoke WIPECLEAR,addr COMANDAIN;call COMANDASCLEAR
mov lvi.imask,LVIF_TEXT
mov lvi.iItem,0
mov lvi.iSubItem,0
mov lvi.pszText,offset PARAM2IN
invoke SendMessage,hList, LVM_INSERTITEM,0, addr lvi
mov lvi.pszText, offset PARAM2IN
INVOKE SendMessage, hList, LVM_SETITEM, 0, addr lvi
;///////////////////////////////////////////////////
mov lvi.imask,LVIF_TEXT
mov lvi.iItem,0
mov lvi.iSubItem,1
mov lvi.pszText,offset PARAM3IN
INVOKE SendMessage, hList, LVM_SETITEM, 0, addr lvi
;/////////////////////////////////////////////////////
;///////////////////////////////////////////////////
mov lvi.imask,LVIF_TEXT
mov lvi.iItem,0
mov lvi.iSubItem,2
mov lvi.pszText,offset PARAM4IN
INVOKE SendMessage, hList, LVM_SETITEM, 0, addr lvi
;///////////////////////////////////////////////////
mov lvi.imask,LVIF_TEXT
mov lvi.iItem,0
mov lvi.iSubItem,3
mov lvi.pszText,offset PARAM5IN
INVOKE SendMessage, hList, LVM_SETITEM, 0, addr lvi
invoke WIPECLEAR,addr PARAM1IN
invoke WIPECLEAR,addr PARAM2IN ;call CLEAR2
invoke WIPECLEAR,addr PARAM3IN;call CLEAR3
invoke WIPECLEAR,addr PARAM4IN
invoke WIPECLEAR,addr PARAM5IN;call CLEAR4
ret
listV ENDP


-----
RE In Progress [!] Coding Hazard [!] Stay Clear of this Cube





Ранг: 387.4 (мудрец)
Активность: 0.170
Статус: Участник
системщик

Создано: 25 апреля 2007 23:54
· Личное сообщение · #2

тяжело читать код, нет полного текста и слишком много низкоуровнего шума. Это весь твой код или ты реверсишь? Может набей прмер на С, посмотрим алго. Ну а потом переведёшь на АСМ, если тебя не устраивает то что выплёвывает компилер.

P.S. то что показывется много message box-ов не подтверждает многопоточность. Если TCP данные обрабатываются через windows messages, а обработчик вызывает MessageBox() то ты палучишь тучу боксов на экране. MessageBox крутит message pump и ты получаешь дикой длинны call stack.




Ранг: 673.3 (! !), 400thx
Активность: 0.40.31
Статус: Участник
CyberMonk

Создано: 26 апреля 2007 17:11
· Личное сообщение · #3

Smisl algoritma ......pri sobitii READ proishodit resiv , potom algoritm ishet simvoli ][ i rasdelaet stroku po 5 buferam ...... v konze prozedura dobavlenia v Listviu . Vot

K sogaleniu s C ya ne nakom ((((

-----
RE In Progress [!] Coding Hazard [!] Stay Clear of this Cube





Ранг: 387.4 (мудрец)
Активность: 0.170
Статус: Участник
системщик

Создано: 26 апреля 2007 19:03
· Личное сообщение · #4

ну а где рушиццо? Call stack в студию




Ранг: 673.3 (! !), 400thx
Активность: 0.40.31
Статус: Участник
CyberMonk

Создано: 28 апреля 2007 23:26
· Личное сообщение · #5

млин это я узнал от того что приложение мое .....с ошибкой завиршается и ошибка постоянно по этому адресу .... этим адресам точнее .... в том то и дело если начну через отладчик ...то все ок !!!!!

-----
RE In Progress [!] Coding Hazard [!] Stay Clear of this Cube




Ранг: 2.0 (гость)
Активность: 0=0
Статус: Участник

Создано: 29 апреля 2007 02:01
· Личное сообщение · #6

mak поставь в качестве JIT - ольгу и посмотри где падает.



Ранг: 14.1 (новичок)
Активность: 0=0
Статус: Участник

Создано: 29 апреля 2007 04:05
· Личное сообщение · #7

mak
Есть код описанны ниже, это код клиента ....сервер шлет много данных которые потом раскладываются по листвью .... каждые 1024 это название + 4 параметра разделеные символами ...и которые после получения расфасовываются по буферам для вставки ..... если поставить перед ресивом месадж бокс ....то будет много месаг ....тоесть есть многопотоковость ....я как то об этом раньше не думал .... получается если данные шлются на локалке ...это код принимает и все ок .....но если в нете ...то тогда клиент рушится ... с ошибкой в области этого кода .....теперь вопрос ......что делать ....как сделать очередь чтоб все по очереди проходили ..или клиент рушится из за ошибки в этом коде ??? Я так подумал что все потоки с одним буфером работают (с одними точнее) и из за этого все рушится ..вот ..Пасиб заранее

Вообще, зачотное описание проблемы.
Да, и программировать сетевые приложения сейчас, полагаясь на какую-то там мнимую "однопоточность", это же полный ерундец. Быстрее переписывайте полностью этот свой код.

А вот за такое вас можно смело вздернуть на рее:

invoke recv,sock,addr COMANDAIN,1024,0;sizeof COMANDAIN,0

invoke lstrlen ,addr COMANDAIN


Кто вам сказал, что буфер COMANDAIN, будет завершен нулем?!
В 99.9% случаев первое падение данного кода будет в вызове lstrlen().



Ранг: 14.1 (новичок)
Активность: 0=0
Статус: Участник

Создано: 29 апреля 2007 08:10
· Личное сообщение · #8

И еще добавлю по общей схеме написания парсера.
Вот так, как вы пишите:
;-------------------------------
XY:
cmp byte ptr [esi],"]"
jz DALEE

DALEE:
cmp byte ptr [esi+1],"["
jz DALEE2

DALEE2:

inc esi
inc esi
dec ecx
dec ecx
;-------------------------------

писать нельзя.
Ибо, подумайте сами, что будет с вашим кодом, если размер текущего буфера уже == 0 или если символ "]" будет последним символом буфера? Правильно - падение, а если в нулевом кольце - то "синька".
В надежных парсерах перед зачитыванием символа по смещению, нужно проверять, что текущий размер буфера позволяет это делать. Т.е. в конкретном случае перед выделенной строкой минимум должна идти такая проверка:

cmp ecx, 2
jl ERROR_BUF_TOO_SMALL


Т.е. приведенный вами код, может вызывать падение в абсолютно разных местах, всё зависит от того какой рендомный треш содержится в буфере переменного размера.




Ранг: 673.3 (! !), 400thx
Активность: 0.40.31
Статус: Участник
CyberMonk

Создано: 29 апреля 2007 11:46 · Поправил: mak
· Личное сообщение · #9

ganjman пишет:
Кто вам сказал, что буфер COMANDAIN, будет завершен нулем?!
В 99.9% случаев первое падение данного кода будет в вызове lstrlen().

Ну думаю хотябы потому что я посылаю строку закончившуюся 0 ..... вот ganjman пишет:
Ибо, подумайте сами, что будет с вашим кодом, если размер текущего буфера уже == 0 или если символ "]" будет последним символом буфера? Правильно - падение, а если в нулевом кольце - то "синька".
В надежных парсерах перед зачитыванием символа по смещению, нужно проверять, что текущий размер буфера позволяет это делать. Т.е. в конкретном случае перед выделенной строкой минимум должна идти такая проверка:

cmp ecx, 2
jl ERROR_BUF_TOO_SMALL

Разделитель последним не будет ...так его не посылаю )))
но думаю эту строчку, а так вообще это да .... просто чето я планировал не так ....вначале бралась длина строки ....и заносилась в ECX потом из каждого цыкла выход был не дожидаясь 0 ECX /// то есть заход в следующий цыкл был уже с инфой от другого ЕСХ...вот ...но это актуально


Строка посылается такого вида --- ххх][xxx][xxx][xxx][xxx

ganjman пишет:
А вот за такое вас можно смело вздернуть на рее:

invoke recv,sock,addr COMANDAIN,1024,0;sizeof COMANDAIN,0

invoke lstrlen ,addr COMANDAIN

Кто вам сказал, что буфер COMANDAIN, будет завершен нулем?!
В 99.9% случаев первое падение данного кода будет в вызове lstrlen().


Может но на локалке все работает отлично ....

Так а что думаете по поводу этого , что при отсутствии СЛИП 10 на локалке приходит ....около 20 -30 строчек и все .... а остальные нет .... может пакет приходит слепленным а я читаю только 1024 при ФДРИД
а остальное удаляется ..... хотя оно бы тогда часть другую приняло ....приходит по алфавиту от А до Д де то .... может не отсылать все подряд пока нет подтверждения


Что с буфером моно сделать ....он ведб один а данные приходят быстро ......
Перерыл много исходников и литературы ...но инфы чето не нашел

-----
RE In Progress [!] Coding Hazard [!] Stay Clear of this Cube





Ранг: 673.3 (! !), 400thx
Активность: 0.40.31
Статус: Участник
CyberMonk

Создано: 29 апреля 2007 12:19
· Личное сообщение · #10

LifeIsPain пишет:
mak поставь в качестве JIT - ольгу и посмотри где падает.

Падает постоянно на команде

movs byte ptr es:[edi],ds:[esi] любой из цикла ...смотря что шлешь

-----
RE In Progress [!] Coding Hazard [!] Stay Clear of this Cube




Ранг: 22.2 (новичок)
Активность: 0.010
Статус: Участник

Создано: 29 апреля 2007 12:21
· Личное сообщение · #11

>Ну думаю хотябы потому что я посылаю строку закончившуюся 0 ..... вот
Интересно, а что помешает (в будущем) кому-то еще послать строку не заканчивающуюся нулем?



Ранг: 309.8 (мудрец), 21thx
Активность: 0.170
Статус: Участник

Создано: 29 апреля 2007 13:31
· Личное сообщение · #12

похоже что код не авторский, ни разу не видел чтобы вместо movsb писали movs byte ptr es:[edi],ds:[esi]

-----
Shalom ebanats!




Ранг: 14.1 (новичок)
Активность: 0=0
Статус: Участник

Создано: 29 апреля 2007 14:39 · Поправил: ganjman
· Личное сообщение · #13

mak пишет:
Разделитель последним не будет ...так его не посылаю )))
Строка посылается такого вида --- ххх][xxx][xxx][xxx][xxx


Вы не посылаете последним, а в принимающем буфере(который вы и парсите) вполне вероятна такая ситуация!
и такой эффект(нехватка нуля в конце) наблюдается вами во всей красе в виде падения приложения.
И ничего свехъестественного в этом нет, ибо это сетевое взаимодействие, где есть такие понятия, как потоки и тайм-ауты, и передача приложению принятых данных п-о-р-ц-и-я-м-и, порой абсолютно различного размера!

Автору топика читать матчасть по безопасному программированию, а также по сетевой модели, взаимодействию и программированию в TCP/IP сетях.

SLV пишет:
похоже что код не авторский

тогда мне вообще не понятно, зачем потребовалось копаться в таком говне.

Всё. Я кончил.

PS: кому нульдей под эту уязвимость?




Ранг: 673.3 (! !), 400thx
Активность: 0.40.31
Статус: Участник
CyberMonk

Создано: 30 апреля 2007 00:09
· Личное сообщение · #14

SLV пишет:
похоже что код не авторский, ни разу не видел чтобы вместо movsb писали movs byte ptr es:[edi],ds:[esi]

не видел чтоб movsb пересылали ... в уч. пособиях везде сказано что формирование movsb идет компилятором .... я так делаю ...WolfHunter пишет:
>Ну думаю хотябы потому что я посылаю строку закончившуюся 0 ..... вот
Интересно, а что помешает (в будущем) кому-то еще послать строку не заканчивающуюся нулем?

ну да это верно ...то там шифровка будет и все остально продумаем ...я поставил проверку там где сказали все работает отлично ....все данные приходят и уходят ....но к сожалению не многопоточное .... пока ... про сеть уже много перелопатил Спасибо )))))

-----
RE In Progress [!] Coding Hazard [!] Stay Clear of this Cube




Ранг: 160.9 (ветеран), 1thx
Активность: 0.050
Статус: Участник

Создано: 30 апреля 2007 10:38
· Личное сообщение · #15

mak пишет:
Падает постоянно на команде

movs byte ptr es:[edi],ds:[esi] любой из цикла ...смотря что шлешь


С какой ошибко то хоть падает?

P.s. Телепатов тут нет. Ну вы поняли о чем я?



Ранг: 14.1 (новичок)
Активность: 0=0
Статус: Участник

Создано: 30 апреля 2007 11:21
· Личное сообщение · #16

Уважаемый, Cigan, понимаете ли вы, что когда размер буфера определен не верно, а потом происходит его побайтовое копирование в другой буфер лимитированного размера, это "плохо" со всех сторон?
Иль ваш мудрый взгляд диагонально проскользил сей бурный опус к блуждающим во тьме познания?




Ранг: 673.3 (! !), 400thx
Активность: 0.40.31
Статус: Участник
CyberMonk

Создано: 30 апреля 2007 12:31
· Личное сообщение · #17

Cigan пишет:
mak пишет:
Падает постоянно на команде

movs byte ptr es:[edi],ds:[esi] любой из цикла ...смотря что шлешь

С какой ошибко то хоть падает?

P.s. Телепатов тут нет. Ну вы поняли о чем я?


Изначально я хотел передавать управление каждому циклу от другого .....но оказалось что неправильно ....поэтому когда в ecx заканчивался счетчик действие продолжалось ..........поставив проверку Проблема решилась .......

НО проблем с буфером приема ...когда пакеты приходят слеплееными а я читаю только 1024 ...и остальные канули в пропасть осталась.... Я никогда неписал такие приложения ..но посмотреть пример тоже негде ... во всех приложениях используется ресив и сенд ..и все . Так как много данных и подряд не пересылаются в примерах. Может у кого то есть пример прриема всех данных
с помощью FDREAD больших размеров для парсинга
P.S де же все ...


ganjman пишет:
Уважаемый, Cigan, понимаете ли вы, что когда размер буфера определен не верно, а потом происходит его побайтовое копирование в другой буфер лимитированного размера, это "плохо" со всех сторон?
Иль ваш мудрый взгляд диагонально проскользил сей бурный опус к блуждающим во тьме познания?

загнул то

-----
RE In Progress [!] Coding Hazard [!] Stay Clear of this Cube





Ранг: 387.4 (мудрец)
Активность: 0.170
Статус: Участник
системщик

Создано: 30 апреля 2007 19:35 · Поправил: s0larian
· Личное сообщение · #18

mak, чувак, во первых, тебе надо проверять что возвращает recv(). Смотри в MSDN доки: htt_://msdn2.microsoft.com/en-us/library/ms740121.aspx

Ф-ция возвращает кол-во байт, если нет ошибок. Теперь, самое главное, для тех кто в танке: ты никогда не предугадаешь, сколько байт пришло в последнем сетевом пакете. То есть, данные которые посылаются в одной проге будут сначала buffered (nagle) а потом разбиты стеком на пакеты. Точные характеристики этих двух процессов зависят от установок буфферезации сокета, количеста вызовов send(), реализации стека и MTU сетевого драйвера.

Поэтому, програмер, ты то есть, должен реализовать структурку "сообщение" которая будет известной длинны (или будет включать поле "размер") и читать из сокета пока не получишь именно нужное (минимальное) кол-во байт, и только потом парсить. Кста, получить ты иногда можешь и несколько сообщений пачкой (то есть когда стек набил их в буфер).

Bottom line: необходимое кол-во вызовов recv() никогда не известно заранее. Ну а потом, как и пишет ganjman, надо осторожно парсить всё полученное. Капиш?




Ранг: 673.3 (! !), 400thx
Активность: 0.40.31
Статус: Участник
CyberMonk

Создано: 30 апреля 2007 21:31
· Личное сообщение · #19

Ясненько ....просто каждый по своему говорит ....я думал что если шлю 1024 + 1024 ....каждые 1024 становятся в очередь ....а при приеме я читаю 1024 разве функция не должна сама ждать пока не получит все 1024 ???? Парсинг терь все ок ....... а вот прием хромает ..... исходников нет полезных ??? по теме ....на васме не нашел ...там все просто

-----
RE In Progress [!] Coding Hazard [!] Stay Clear of this Cube





Ранг: 387.4 (мудрец)
Активность: 0.170
Статус: Участник
системщик

Создано: 01 мая 2007 01:30 · Поправил: s0larian
· Личное сообщение · #20

mak пишет:
а при приеме я читаю 1024 разве функция не должна сама ждать пока не получит все 1024 ????

С чего ты взял что recv(1024) значит "ждать 1024 байта"? Ты доку читал? Там все описано досканально.

Так вот,

int recv(socket, buff, buff_len, flags)

и buf_len показывает сколько байт API имеет право загнать в твой буфер. В сокт может прийти и 20 кил с момента когда ты последний раз вызывал recv()....

Ну а если ты хочешь заставить recv() ждать какого-то определённого кол-ва байтов, то вызывай setsockopt()

З.Ы. ты, кста, попробывал бы написать несколько взамосвязанных, полностью построенных фраз с пунктуаций




Ранг: 673.3 (! !), 400thx
Активность: 0.40.31
Статус: Участник
CyberMonk

Создано: 01 мая 2007 21:58
· Личное сообщение · #21

s0larian пишет:
mak пишет:
а при приеме я читаю 1024 разве функция не должна сама ждать пока не получит все 1024 ????
С чего ты взял что recv(1024) значит "ждать 1024 байта"? Ты доку читал? Там все описано досканально.

Так вот,

int recv(socket, buff, buff_len, flags)

и buf_len показывает сколько байт API имеет право загнать в твой буфер. В сокт может прийти и 20 кил с момента когда ты последний раз вызывал recv()....

Ну а если ты хочешь заставить recv() ждать какого-то определённого кол-ва байтов, то вызывай setsockopt()

З.Ы. ты, кста, попробывал бы написать несколько взамосвязанных, полностью построенных фраз с пунктуаций

Пасибо за разяснение! А по поводу многопоточного приема есть пример у кого нибудь ???!!!

-----
RE In Progress [!] Coding Hazard [!] Stay Clear of this Cube




Ранг: 163.7 (ветеран)
Активность: 0.070
Статус: Участник

Создано: 02 мая 2007 11:05 · Поправил: S_T_A_S_
· Личное сообщение · #22

mak пишет:
в уч. пособиях везде сказано что формирование movsb идет компилятором .... я так делаю

Ты не понял
руками пишут (как и ты сейчас _сам_ сделал) movsb или (значительно реже) movs byte ptr [edi],[esi] А форма movs byte ptr es:[edi],ds:[esi] выдаётся дизассеблерами

ganjman пишет:
тогда мне вообще не понятно, зачем потребовалось копаться в таком говне

Трояна чужего ковыряет небось




Ранг: 673.3 (! !), 400thx
Активность: 0.40.31
Статус: Участник
CyberMonk

Создано: 02 мая 2007 12:42
· Личное сообщение · #23

S_T_A_S_ пишет:
mak пишет:
в уч. пособиях везде сказано что формирование movsb идет компилятором .... я так делаю
Ты не понял
руками пишут (как и ты сейчас _сам_ сделал) movsb или (значительно реже) movs byte ptr [edi],[esi] А форма movs byte ptr es:[edi],ds:[esi] выдаётся дизассеблерами

ganjman пишет:
тогда мне вообще не понятно, зачем потребовалось копаться в таком говне
Трояна чужего ковыряет небось


Ну нет ...честно я не знал что моно так писать ...так как думал что компилятор формирует такую команду из того что я пишу .....

Нет не ковыряю ...еслиб это помогло , было бы круто ....раньше пол года назад ковырял ..смотрел как построен обмен ...и оказался как у всех исходников на васме...

Хоть убей я не пойму почему , когда посылается много инфы доходит не вся .... я сделал многопоточный прием . на каждый ФДРИД свой поток ,для обработки свои буфера. Если даже некоторые приходят слепленными ,как их обработать ???? Ни кто не знает у кого спрашивал

-----
RE In Progress [!] Coding Hazard [!] Stay Clear of this Cube





Ранг: 387.4 (мудрец)
Активность: 0.170
Статус: Участник
системщик

Создано: 02 мая 2007 19:16 · Поправил: s0larian
· Личное сообщение · #24

mak пишет:
А по поводу многопоточного приема есть пример у кого нибудь ???!!

То есть? У тебя сколько сокетов? Один сокет должен обрабатываться из одного потока, а иначе ты просто получишь классические raced conditions.

По поводу приёма/передачи: я же отписал уже, сделай структурку типа:


#pragma pack(push)
#pragma pack(1)

enum MessageType
{
MSG_HELLO = 100
};

struct MessageHeader
{
uint32 size;
MessageType type;
};

struct Hello
{
byte version;
uint32 id;
// whatever you want goes here....
};
#pragma pack(pop)


Читаешь сначала sizeof(MessageHeader), потом читаешь ещё header.size байтов. Получив все данные смотришь header.type, и если это MSG_HELLO делаешь cast и разбираешь полученный Hello.

З.Ы. TCP, концептуально, даёт тебе поток данных и гарантирует доставку и порядок. Понятия "сообщений" тут нет и, следвательно, ты их реализуешь.




Ранг: 673.3 (! !), 400thx
Активность: 0.40.31
Статус: Участник
CyberMonk

Создано: 02 мая 2007 21:58
· Личное сообщение · #25

s0larian пишет:
mak пишет:
А по поводу многопоточного приема есть пример у кого нибудь ???!!
То есть? У тебя сколько сокетов? Один сокет должен обрабатываться из одного потока, а иначе ты просто получишь классические raced conditions.

По поводу приёма/передачи: я же отписал уже, сделай структурку типа:


#pragma pack(push)
#pragma pack(1)

enum MessageType
{
MSG_HELLO = 100
};

struct MessageHeader
{
uint32 size;
MessageType type;
};

struct Hello
{
byte version;
uint32 id;
// whatever you want goes here....
};
#pragma pack(pop)


Читаешь сначала sizeof(MessageHeader), потом читаешь ещё header.size байтов. Получив все данные смотришь header.type, и если это MSG_HELLO делаешь cast и разбираешь полученный Hello.

З.Ы. TCP, концептуально, даёт тебе поток данных и гарантирует доставку и порядок. Понятия "сообщений" тут нет и, следвательно, ты их реализуешь.


Плиз переведи на асм или на асме ничего не заволялось... я так понял ты строку написал ...структуру пакета ??? Я не понимаю С++ или что это ...

-----
RE In Progress [!] Coding Hazard [!] Stay Clear of this Cube





Ранг: 673.3 (! !), 400thx
Активность: 0.40.31
Статус: Участник
CyberMonk

Создано: 04 мая 2007 13:31
· Личное сообщение · #26

Я понял о чем ты говоришь ..... но смотри .... если я посылаю в нете много этих структур ....уже сформированных ............ доходят только первые .......я попробовал слип в 50 установить и доходит больше !!!!! как это обьяснить ? Строка посылается такого вида --- ххх][xxx][xxx][xxx][xxx ...это каждый сенд ....сендов может быть около 250 ...... если они приходят слепелны ...то тогда вид такой будет ? Строка посылается такого вида --- ххх][xxx][xxx][xxx][xxx+ххх][xxx][xxx][xxx][xxx+ххх][xxx][xxx][xxx][xx x
и часть я потеряю при парсинге ? ....правильно ???

-----
RE In Progress [!] Coding Hazard [!] Stay Clear of this Cube




Ранг: 10.2 (новичок)
Активность: 0=0
Статус: Участник

Создано: 04 мая 2007 14:32
· Личное сообщение · #27

Песдетс... Посылай не
xxx][xxx][xxx][xxx][xxx + ... + xxx][xxx][xxx][xxx][xxx
а
SIG|LEN|xxx][xxx][xxx][xxx][xxx + ... + SIG|LEN|xxx][xxx][xxx][xxx][xxx
Короче введи разметку потока. А еще проще заюзать COBS байтстаффинг. Также учти фрагментацию сообщений. Ты можешь просто не считать конец сообщения в свой буфер или конец мог еще не прийти ести размер сообщения > MTU. Для корректного приёма надо влезшую часть сообщения сдвинуть в начало буфера и вызвать recv, где в качестве буфера надо указать <АДРЕС БУФЕРА> + <РАЗМЕР ФРАГМЕНТА>.



Ранг: 65.7 (постоянный)
Активность: 0.050
Статус: Участник

Создано: 04 мая 2007 22:32 · Поправил: Halt
· Личное сообщение · #28

похоже он просто не понимает
смысл такой ты послал 1024 байта и еще 1024 байта, они ушли нормально, а на компьютере с сервером (или клиентом которому ты их эти 1024 послал) винда вдруг решила дефрагментировать свой загрузочный сектор (это например) в результате чего по команде recv тебе прилетело 15 байт потом через пару секунд еще 15 а потом 2048. Вопрос как узнать сколько посылали(именно не длинну сообщения, а размер отосланных данных (которые возвращает send после выполнения, опять же тут тоже нужна проверка а все ли было отправлено?? и если невсе то дослать остаток) ), т.е. если ты не знаешь то примешь только первые 15 байт и все.. а остальное пролетит мимо выринтов выхода тут 2 либо к соообщению прибавлять контрольный (завершающий) симол (как 0 в конце текстовой строки) либо как уже было сказано выше использовать в пакете длинну сообщения в результате общий вид схемы приема будет такой :

клиент:
отослал 1024

сервер(при использовании разделяющего символа):
принял колько-то
посмотрел встречается ли в принятом этот разделяющий символ
да - скопировал симвлы до него и отправил на обработку. конец.
нет - скоппировал принятые данные в переменную (буфер и т.д.) и ждет дальше до тех пор пока либо не примет (по условию ДА) все либо (как делают продвинутые девелоперы) не истечет некоторый таймаут и можно будет смело орать про ошибку сети.

при условии использования длинны пакета в сообщении условие будет таким:
принял сколько-то
взял 4 символ (ну или с 4 по 7 например)) (я знаю что там длинна пакета) сравнил с тем что пришло за вычетом данных о самой длинне (которые с 4 до 7 символа) , и за вычетом сигнатуры пакета (а твой ли это вообще пакет или кто-то ддос атаку устроил) (если используешь) в результате :
- да, все пришло, - обработка.конец
- нет:
-пришло больше добираем из пришедшего данные до длинны сообщения (которая пришла раньше) ну а остальное это уже новый пакет. законченый пакет на обработку и ждем досылки данных длял нового пакета.
- пришло меньше - записываем в буфер и ждем отстатки.


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

ЗЫ да и еще разделяющий сомвол не должен встречаться в тексте сообщения а иначе будет жопа с ручкой... что в условиях пересылки например ехе файла нереально.. поэтому лучшим выходом будет указание длинны отосланного пакета.
да и еще длинна части пакета отвечающая за размер должна быть одинаковой, а иначе непонятно сколько брать... если число меньше - просто ддополняй его нулями в начале ...




Ранг: 673.3 (! !), 400thx
Активность: 0.40.31
Статус: Участник
CyberMonk

Создано: 05 мая 2007 16:11 · Поправил: mak
· Личное сообщение · #29

Да я понял .....клиент уже так сделан ....только вот проблема не в получении а в отправке ...на Сервере я отправляю без слип 10 .....и валится .....а при слип 10 на локалке ок ...в инете опять тоже самое ....

Примера нет ни у кого ?

-----
RE In Progress [!] Coding Hazard [!] Stay Clear of this Cube





Ранг: 387.4 (мудрец)
Активность: 0.170
Статус: Участник
системщик

Создано: 07 мая 2007 19:38 · Поправил: s0larian
· Личное сообщение · #30

mak, ну это уже клиника просто.... мы же с Halt-ом тебе уже всё расписали и разложили.

1) перечитай наши посты
2) напиши и клиента и сервера на С/Delphi/VB
3) перепиши код на асме
4) 5) 6) поправь там все косяки парсинга и управления памятью


. 1 . 2 . >>
 eXeL@B —› Программирование —› Рушится при Recv в нете но не локалке
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати