Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Nov 21 06:16
    rlebeau commented #270
  • Nov 20 13:33
    evgeny-k opened #270
  • Nov 16 18:35
    rlebeau commented #201
  • Nov 14 18:08
    wqmeng commented #201
  • Nov 14 18:04
    arvanus commented #201
  • Nov 14 17:43
    wqmeng commented #201
  • Nov 14 17:37
    arvanus commented #201
  • Nov 14 17:31
    wqmeng commented #201
  • Nov 14 12:00
    arvanus commented #201
  • Nov 14 09:07
    wqmeng commented #201
  • Nov 14 09:05
    wqmeng commented #201
  • Oct 30 16:15
    rlebeau edited #260
  • Oct 16 04:22
    rlebeau labeled #269
  • Oct 16 04:22
    rlebeau opened #269
  • Oct 08 19:00

    Fulgan on Restructure

    Bug fix for a typo in TIdIMAP4.… (compare)

  • Oct 08 19:00

    Fulgan on master

    Bug fix for a typo in TIdIMAP4.… (compare)

  • Oct 02 21:00

    Fulgan on Restructure

    Updating TIdIMAP4's InternalSea… (compare)

  • Oct 02 21:00

    Fulgan on master

    Updating TIdIMAP4's InternalSea… (compare)

  • Sep 20 21:50

    Fulgan on master

    Embarcadero patch for race cond… (compare)

  • Sep 20 21:50

    Fulgan on Restructure

    Embarcadero patch for race cond… (compare)

fan_tangshan
@sainimu78
Some real time requirement
Remy Lebeau
@rlebeau
TIdTCPClient and TIdTCPServer use TCP, hence their names. Do you understand how TCP actually works? Do you understand that there is no 1-to-1 relationship between sends and reads in TCP (unlike in UDP)? You could sent 100 bytes 1 time, but read 1 byte 100 times. TCP guarantees the bytes are delivered, and in the right order, but how you send the bytes does not affect how you read the bytes and vice versa.
In any case, regarding the 2-sends 1-read issue, it likely has to do with how ReadBytes(-1) interacts with the InputBuffer. After the OnExecute event exits, the server calls IOHandler.Connected before firing OnExecute again. Connected performs a read, so it is possible that bytes are getting read into the InputBuffer and a subsequent ReadBytes(-1) is not checking for them before waiting for more bytes to arrive on the socket. If you were reading the packet header, like you should be, you wouldn't have that issue.
fan_tangshan
@sainimu78
I see, I know how to do
fan_tangshan
@sainimu78
I start a thread.
fan_tangshan
@sainimu78
A connection thread in client
In thread.Execute
while(Terminated = False)do
if(client.Connected = False)then
client.Disconnect;
Sleep(100);
The client will get Run Error 204 while server transferring data in client transferring way.
The transferring way is
blob
blob
It is just like you told me before @rlebeau
fan_tangshan
@sainimu78
Oh, sorry, my fault, I never thought it is a misusing of converting PByte to TIdBytes because I specified the size to IoHandler.Write.
fan_tangshan
@sainimu78
Or the other way of asking that how to detect disconnection on TIdTCPClient ?
fan_tangshan
@sainimu78
Here is my server.OnExecute doing
blob
Toggles between ReadBytes(8) and ReadBytes(argConn.bufSize)
blob
fan_tangshan
@sainimu78
TIdTCPClient.Connected is not thread safe, I think.
A mutex needs to be added on TIdTCPClient.IoHandler.ReadBytes call in the receive thread and on TIdTCPClient.Connected in the connection thread.
I found that the client receive thread can be aborted by the exception of the calling IoHandler.ReadBytes, then the problem solved.
Remy Lebeau
@rlebeau
You really shouldn't be calling Connected at all. Let the IOHandler throw an exception during read/write operations if the socket has been disconnected.
If you don't want the thread to terminate, catch the exception
fan_tangshan
@sainimu78

What Is wrong in this implementation?

In the client, I start a receive thread:
--the receive thread in the client:
----TIdTCPClient.IoHandler.ReadBytes
in the server:
--OnExcute:
----AContext.Connection.IoHandler.ReadBytes
If I first start the test transferring of the client sending data of < 80000 bytes to the server 10000 times and then do the same test reverse of the server sending to the client, there is nothing abnormal.
But if I first start the test of the server sending to the client and then the transferring speed becomes very low when do the test of the client sending to the server.

Remy Lebeau
@rlebeau
I can't answer that without seeing your actual code
fan_tangshan
@sainimu78
The test is one app sends data in size of < 7kb 100000 times to the other one.
If I never click the Server Send button to start the test of the server sending to the client and just do test the client to the server, it takes about 40~50 seconds in every test.
But if I click the Server Send once, the test of the client to the server sending will take apparently longer time than before.
QQ图片20160811020720.png
Here is the common read write procedure
blob
fan_tangshan
@sainimu78
The server
blob
The client
blob
fan_tangshan
@sainimu78
So simple test it is, I believe you'd tested it at the very beginning
Remy Lebeau
@rlebeau
well, it kind of makes sense, if you take into account that the client code is single-threaded but the server code is multi-threaded, so you are likely getting task switches during the server-to-client sending that are slowing it down compared to the client-to-server sending. Remember, TIdTCPServer runs each client in its own worker thread. Even if there is only 1 client connected, there are still other threads running (the main UI thread, the server's listening thread, etc) that the OS has to service in a timely manner.
fan_tangshan
@sainimu78
No, I don't think so. It's normal when I test the client-server sending with fixed bytes.
There may have some bad implementations doing with that.
blob
fan_tangshan
@sainimu78
After doing the server-client sending test, every client-server sending makes CPU usage rate high. If you are listening music you can hear lag sound.
So I guess the non-fixed bytes sending causes some threads work so hard in TIdTCPServer if the TIdContext.Connection.IoHandler cached something when Write().
davidpn
@davidpn
I thought I cancelled Lex's post that you replied to in the .winsock group.. it was an out-and-out lie (a repeat of the same one, I know)
fan_tangshan
@sainimu78
Is it not a problem? @rlebeau
Remy Lebeau
@rlebeau
by default, the IOHandler does not cache anything when sending. The data is passed directly to the underlying socket and the OS does all of the caching
I don't know what elsee to tell you. There is no memory leak in Indy. Plenty of people use Indy for a long time, a leak would have been noticed before. Something else has to be going on in your environment. Maybe your test code is fragmenting memory instead of leaking it. who knows.
davidpn
@davidpn
What's the reasoning behind checking for PassThrough when catching the exception in TIdSSLIOHandlerSocketOpenSSL.StartSSL (IdSSLOpenSSL unit)?
The reason I ask is that when using SSL through a proxy, PassThrough is set to True, so it's impossible to catch the EIdOSSLCouldNotLoadSSLLibrary exception
Remy Lebeau
@rlebeau
At that stage, OpenSSL is simply being pre-initialized but SSL/TLS is not actually being used yet, and may or may not ever be used depending on the caller's needs, so the exception is silent caught to allow the unencrypted connection to proceed. At a later time, if PassThrough is ever set to false to activate SSL/TLS, then the exception will be raised to the caller. Even through a proxy, PassThrough has to be set to false eventually.
davidpn
@davidpn
OK.. I think the easiest way out is going to be to call Load before a connection is attempted
Remy Lebeau
@rlebeau
just make sure you call it in a thread-safe manner to avoid overlapping loads
davidpn
@davidpn
thanks
Ludwig Behm
@lbehm
Hy everyone, I'm trying to overwrite a response generated by datasnap (running on TIdHTTPWebBrokerBridge). TDSRESTWebDispatcher sends eventual StatusCode 401 and to hide the annoying browser login window, I want to send StatusCode 403 instead. After trying several DataSnap specific events which show absolutely no effect, I would like to try to intercept the response on the Indy-level.
Is there a nice way to hook into the server response and overwrite every StatusCode of 401 with 403? PS: I have access to an Intercept interface.
Remy Lebeau
@rlebeau
If you don't have access to the actual source that is populating the original HTTP response, you can't really change its behavior. With an Intercept, it might be possible to alter the data as it is being sent, but that would require parsing the HTTP data that passes through the Intercept. The data is arbitrary bytes from the Intercept's perspective, so you would need to write a stateful parser in case you get multiple OnSend events. I would be more inclined to suggest figuring out why DataSnap is sending a 401 reply to begin with and see if there is a way to change that behavior, instead of trying to modify the response data after the fact. Especially since modifying the 401 may break non-browser clients that could have logged in without prompting the user. Why are you using a web browser to access a DataSnap REST server in the first place?
Ludwig Behm
@lbehm
Thank you for the fast answer! I'm writing a AngularJS based browser-only-app and access the backend via the rest interface. And sadly I've found no possibility to circumvent either the browser behavior (showing the login box) or that of datasnap (sending 401 if TDSAuthenticationManager is present but no login/session data).
Remy Lebeau
@rlebeau
Sorry, I don't know anything about Angular or DataSnap or how they work.
Ludwig Behm
@lbehm
okay^^ do you maybe know of some other rest-framework which is compatible with c++builder? I just found a delphi based one =)
Remy Lebeau
@rlebeau
You can use Delphi code and Delphi components in C++Builder.