This is definitely the first time I ask about this topic. Not the second time, either. I guess I'm just dumb enough to not be able to get it all working even after reading many replies to my earlier questions :)
May problem again, is that I have a port forwarder type of application. Local clients send to my server, and the server forward the traffic to remote servers. Because the local client can send real fast, the data will be cached in twsocket's internal send buffer. Sometimes, it reaches a few hundred MBytes, which is not good. My solution to this is to pause local client traffic if the BufferedByteCount of remote socket is above 8192 bytes. Here is the code: procedure TComm.WSocketServerClientDataAvailable(Sender: TObject; Error: Word); begin ... len := Receive(@DataRcv, 65536); ... if TransportSocket.BufferedByteCount > 8192 then begin Log('Client paused ID=' + IntToStr(Id) + ' BufferedByteCount=' + IntToStr(TransportSocket.BufferedByteCount)); TClientSocket(Sender).ComponentOptions := ComponentOptions + [wsoNoReceiveLoop]; TClientSocket(Sender).Pause; exit; end; ... end; However, the client socket does not seem to pause, as I'm seeing tons of these entries in my log window (paused but not really paused): Client paused ID=7 BufferedByteCount=22878 Client paused ID=7 BufferedByteCount=22878 Client paused ID=7 BufferedByteCount=22878 Client paused ID=7 BufferedByteCount=22878 Client paused ID=7 BufferedByteCount=22878 I'm also logging Resume() calls but according to the log, Resume() were not called when the Pause() calls happened. Not wanting to waste others' time replying to me again, I dig the old emails on this matter and read them again but couldn't find what I'm doing wrong. Below are some excerpts from past emails. It could be compiled in one of the wiki pages. -- Best regards, Jack [From Francios] It (Pause) suppress async notification. So you don't receive events anymore but I/O continue as much as winsock can, for example filling his receive buffer. You can't ignore OnDataavailable event ! If you don't call Receive from OnDataAvailable event, the event will be triggered again and again until you read the data. You'll enter an infinite loop. Calling Pause will stop OnDataAvailable from being triggered, ... Pause only affect winsock notification. It stops notifications from winsock but if data is already in, you have to read it. Try the option wsoNoReceiveLoop, it may help to stop delivering of already received data. If you use the option and pause the socket, you will not be notified of any data already received and waiting in the buffer. So when you resume, you should probably call Receive once to check for remaining data. wsoNoReceiveLoop tell the component to not loop until the message queue has no more FD_READ messages. When a loop is done (default) the component receive data as fast as possible. This maybe result is heavy load on the computer when the network is very fast compared to the CPU speed. It (wsoNoReceiveLoop) shouldn't have any impact on the high level protocol, except speed. Speaking about your application: are you sure you still receive data ? From OnDataAvailable event handler, you must receive everything or you enter an infinite loop when wsoNoReceiveLoop is not activated and if activated but you don't call Receive, then you don't get any notification before you cxall Receive. If you call Pause, obviously you are no more notifyed when data comes in. This will fill the receive buffer until full and at that time the peer will recive the zero window message. Before timeout you must call resume and probably Receive as well to restart the receiving process. [From Wilfried] - Pause will stop notification from winsock. If there is already data received then OnDataAvailable will keep on firing for a while until you have received. After that winsock buffer will fill but no notification. When winsock buffer is full then sender will stop sending data. - Resume will turn notification back on, so filled up receive buffer from winsock will fire onDataAvailable again. - if you set wosNoReceivedLoop and you do NOT receive in OnDataAvaliable then it will also not fire again until you call receive. This means that you have to call Receive outside the OnDataAvailable to turn it on again. - A combination of both should be working also. You call pause, and when you are in paused state you dont want to receive even if there is already somethign to receive as you explained in a previous mail. Then you do the wsoNoReceivLop; I "think" if combine both, and you call Resume that OnDataAvailable will fire again without calling Receive outside of it. You can try it easely of course. Pleas let us know, this is valuable information. -- To unsubscribe or change your settings for TWSocket mailing list please goto http://www.elists.org/mailman/listinfo/twsocket Visit our website at http://www.overbyte.be