Heya all.
I am having issues with a client I'm coding for IRC.
The problem relates to flooding of a single socket connection.
Some IRC commands can generate a lot of packets quite fast.
My application falls over when this happens.

Here is the source of my socket read procedure, called from the FD_READ handler. If you can see any obvious problems with this implementation, I'd love to hear your suggestions.
I wanted to try not to use a state-based procedure, because I am unsure of the asynchronicity of IRC servers in their replies, ie, what is the likelihood of getting some arbitrary message in the middle of a larger reply, say a PING during a /LIST ??
Please try this app, login to IRC and type /LIST (ENTER) and u will see the problem I refer to.

;This procedure globally allocates a chunk of memory for data,
;then reads the data into it, character by character.
;It seeks to find complete lines terminated by linefeeds,
;and won't act iuntil it has a complete line.
;In this manner it can handle lines split over two or more packets,
;should an incomplete line be issued on the end of a packet.

ReadData PROC
LOCAL sizetoread:DWORD
LOCAL mHandle:DWORD ;Handle to our allocated memory
LOCAL buffer:DWORD ;Pointer to the same
LOCAL outbuf[256]:BYTE
szText szData,"Incoming %lu"
invoke ioctlsocket,hMommaSocket,FIONREAD,addr sizetoread ; Check the number of bytes available to read from the socket
Moore:
mov eax,sizetoread
inc eax
push eax
invoke GlobalAlloc,GHND,eax ; allocate memory enough for the data to read from the socket
mov mHandle,eax
invoke GlobalLock,eax
mov buffer,eax
pop eax
invoke RtlZeroMemory,buffer,eax
invoke recv,hMommaSocket,buffer,sizetoread,0 ; Read the data from the socket
.if eax!=SOCKET_ERROR
sub sizetoread,eax ; Save the actual number of bytes read from the socket
; BEWARE! The value returned from ioctlsocket and the actual number of bytes
; read in from the socket are not always equal.
push eax
invoke RtlZeroMemory,addr lilbuf,sizeof lilbuf
pop eax
invoke wsprintf,addr lilbuf,addr szData,eax
invoke SendMessage,hStatus,SB_SETTEXT,0,ADDR lilbuf

lea edi,linebuffer
.while byte ptr!=0 ;skip possible incomplete line
inc edi ;leftover from end of last packet
.endw

mov esi,buffer
push edi
.while byte ptr!=0
.if byte ptr==13 ;Ignore Carriage Returns (skip em)
inc esi
.else
mov al,byte ptr
mov byte ptr,al
inc esi
inc edi
.if al==10 ;We have a complete line (includes LineFeed)
mov byte ptr,0

szText findme1,"NOTICE AUTH"
szText findme2," 001 %s"
szText findme3," 002 %s"
szText findme4," 003 %s"
szText findme5," 004 %s"
szText findme6," 005 %s"
szText findme7," 251 %s"
szText findme8," 252 %s"
szText findme9," 254 %s"
szText findmea," 255 %s"
szText findmeb," 266 %s"
szText findmec," 372 %s"
szText findme1a,"%s MODE %s"
szText findme1b,"NOTICE %s"
szText ChanName," 322 %s "
szText szPing,"PING "
szText szPong,"PONG "

invoke RtlZeroMemory,addr lilbuf,sizeof lilbuf
invoke wsprintf,addr lilbuf,addr szPing,addr NickName
invoke InString,1,addr linebuffer,addr lilbuf
.if eax!=0
add eax,4
lea edi,linebuffer
add edi,eax
push edi
invoke RtlZeroMemory,addr outbuf,sizeof outbuf
invoke lstrcat,addr outbuf,addr szPong
pop edi
invoke lstrcat,addr outbuf,edi
invoke lstrlen,addr outbuf
invoke send,hMommaSocket,addr outbuf,eax,0
jmp my2
.endif

invoke RtlZeroMemory,addr lilbuf,sizeof lilbuf
invoke wsprintf,addr lilbuf,addr findme1b,addr NickName
invoke InString,1,addr linebuffer,addr lilbuf
.if eax!=0
jmp matched
.endif

invoke InString,1,addr linebuffer,addr findme1
.if eax!=0
invoke SendMessage,hRichEd,EM_SETCHARFORMAT,SCF_SELECTION,addr charformat01
lea edi,linebuffer
inc edi
.while byte ptr!=":"
inc edi
.endw
jmp my2
.endif

invoke RtlZeroMemory,addr lilbuf,sizeof lilbuf
invoke wsprintf,addr lilbuf,addr findme2,addr NickName
invoke SendMessage,hRichEd,EM_SETCHARFORMAT,SCF_SELECTION,addr charformat02
invoke InString,1,addr linebuffer,addr lilbuf
.if eax!=0
lea edi,linebuffer
jmp matched
.endif

invoke RtlZeroMemory,addr lilbuf,sizeof lilbuf
invoke wsprintf,addr lilbuf,addr findme3,addr NickName
invoke InString,1,addr linebuffer,addr lilbuf
.if eax!=0
jmp matched
.endif

invoke RtlZeroMemory,addr lilbuf,sizeof lilbuf
invoke wsprintf,addr lilbuf,addr findme4,addr NickName
invoke InString,1,addr linebuffer,addr lilbuf
.if eax!=0
jmp matched
.endif

invoke RtlZeroMemory,addr lilbuf,sizeof lilbuf
invoke wsprintf,addr lilbuf,addr findme5,addr NickName
invoke InString,1,addr linebuffer,addr lilbuf
.if eax!=0
jmp matched
.endif

invoke RtlZeroMemory,addr lilbuf,sizeof lilbuf
invoke wsprintf,addr lilbuf,addr findme6,addr NickName
invoke InString,1,addr linebuffer,addr lilbuf
.if eax!=0
jmp matched
.endif

invoke RtlZeroMemory,addr lilbuf,sizeof lilbuf
invoke wsprintf,addr lilbuf,addr findme7,addr NickName
invoke InString,1,addr linebuffer,addr lilbuf
.if eax!=0
jmp matched
.endif

invoke RtlZeroMemory,addr lilbuf,sizeof lilbuf
invoke wsprintf,addr lilbuf,addr findme8,addr NickName
invoke InString,1,addr linebuffer,addr lilbuf
.if eax!=0
jmp matched
.endif


invoke RtlZeroMemory,addr lilbuf,sizeof lilbuf
invoke wsprintf,addr lilbuf,addr findme9,addr NickName
invoke InString,1,addr linebuffer,addr lilbuf
.if eax!=0
jmp matched
.endif

invoke RtlZeroMemory,addr lilbuf,sizeof lilbuf
invoke wsprintf,addr lilbuf,addr findmea,addr NickName
invoke InString,1,addr linebuffer,addr lilbuf
.if eax!=0
jmp matched
.endif

invoke RtlZeroMemory,addr lilbuf,sizeof lilbuf
invoke wsprintf,addr lilbuf,addr findmeb,addr NickName
invoke InString,1,addr linebuffer,addr lilbuf
.if eax!=0
jmp matched
.endif

invoke RtlZeroMemory,addr lilbuf,sizeof lilbuf
invoke wsprintf,addr lilbuf,addr findme1a,addr NickName,addr NickName
invoke InString,1,addr linebuffer,addr lilbuf
.if eax!=0
mov LoggedIn,1
jmp matched
.endif


invoke RtlZeroMemory,addr lilbuf,sizeof lilbuf
invoke wsprintf,addr lilbuf,addr findmec,addr NickName
invoke InString,1,addr linebuffer,addr lilbuf
.if eax!=0
jmp matched
.endif




;*** What to do with an unrecognized line
lea edi,linebuffer
jmp my2





matched: push eax
mov ecx,charformat02.yHeight
mov edx,ecx ;reduce current size by
shr edx,6 ;1/64 of current size
sub ecx,edx
mov charformat02.yHeight,ecx

;//Fade Text Color
mov ecx,charformat02.crTextColor
mov ebx,ecx ;Split into RGB bytes
shr ebx,4 ;divide each by 16
mov al,bl ;and subtract from current ie
and al,15 ;color=color-(color/16)
shl eax,8
shr ebx,8
mov al,bl
and al,15
shl eax,8
shr ebx,8
mov al,bl
and al,15
mov ebx,eax
sub ecx,ebx
mov charformat02.crTextColor,ecx


pop ebx
invoke lstrlen,addr lilbuf
add eax,ebx
lea edi,linebuffer
add edi,eax
my2: .if byte ptr==":"
inc edi
.endif
invoke SendMessage,hRichEd,EM_GETLINECOUNT,0,0
invoke SendMessage,hRichEd,EM_LINEINDEX,eax,0
invoke SendMessage,hRichEd,EM_SETSEL,eax,-1
invoke SendMessage,hRichEd,EM_REPLACESEL,0,edi
jmp owt


owt: invoke RtlZeroMemory,addr linebuffer,sizeof linebuffer
lea edi,linebuffer

.endif
.endif
.endw
pop edi


invoke GlobalUnlock,buffer
invoke GlobalFree,mHandle
.endif
.if sizetoread!=0

jmp Moore
.endif
ret
ReadData ENDP
Posted on 2002-06-15 12:45:01 by Homer
Well I must have been tired - I forgot to post the link to the executable !! Silly Homer.
Here 'Tis
Posted on 2002-06-15 16:05:48 by Homer