Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Dec 06 18:14
    rlebeau commented #183
  • Dec 06 18:00
    JPeterMugaas commented #183
  • Dec 06 17:42
    rlebeau commented #183
  • Dec 06 17:42
    rlebeau commented #183
  • Dec 06 17:41

    rlebeau on OpenSSL-1.1.x

    (compare)

  • Dec 06 17:18
    rlebeau commented #270
  • Dec 06 17:17
    jgv-Flexsys commented #183
  • Dec 06 17:10
    rlebeau commented #183
  • Dec 05 15:04
    Fulgan commented #270
  • Dec 05 13:25
    winkelsdorf commented #183
  • Dec 05 13:23
    winkelsdorf commented #183
  • Dec 03 22:30

    rlebeau on master

    Correctly define timezone funct… Merge pull request #272 from Bi… (compare)

  • Dec 03 22:30
    rlebeau closed #272
  • Dec 03 21:15

    rlebeau on master

    Fixing compiler errors in TIdIP… (compare)

  • Dec 03 20:50
    Bi0T1N opened #272
  • Dec 03 01:33

    rlebeau on master

    Fix for missing declaration of … Fix for compiler error in Local… Merge branch 'master' of https:… and 2 more (compare)

  • Dec 02 20:27

    rlebeau on master

    Update IdGlobal.pas Fix for co… (compare)

  • Dec 01 20:17

    rlebeau on master

    Update IdGlobal.pas Fix for mi… (compare)

  • Dec 01 10:46
    geoffsmith82 commented #192
  • Nov 30 16:54

    rlebeau on master

    Update IdGlobal.pas Fix for co… (compare)

phy0292
@phy0292
Very good
phy0292
@phy0292
@rlebeau In addition to the last time I say the way,If use Z_SYNC_FLUSH instead of Z_NO_FLUSH. It can also eliminate BUG. I do not know will not reduce the compression capability.
phy0292
@phy0292
Oh, no, the second approach is wrong.
davidpn
@davidpn
@rlebeau There was a post in .winsock about IdZLib not compiling.. not sure if it's because of stuff you were were doing recently
davidpn
@davidpn
is Indy supposed to handle IPv6 "automatically"?
Remy Lebeau
@rlebeau
not "automatically", no. You need to manually set the connection's IPVersion property to Id_IPv6 (unless you recompile Indy with IdIPv6 defined in IdCompilerDefines.inc, then IPVersion will default to Id_IPv6). In the case of TIdHTTP specifically, it obtains server info from a URL instead of set properties, so if you want to connect to an HTTP/S server using IPv6, you need to wrap the host portion of the URL in brackets. RFCs 2732 and 3986 require brackets around IPv6 IP addresses only, but TIdHTTP currently requires brackets around hostnames as well if you want it to perform an IPv6 DNS lookup. Indy is currently dependant on the IPVersion property being set and is not coded to resolve a hostname to both IPv4 and IPv6 at the same time and then attempt every address reported until a connection is successful. It lookups a hostname to either IPv4 or IPv6 only and then attempts a connection to the first IP reported only.
davidpn
@davidpn
ok, is there a way of determining whether an OS supports IPv6 or do we need to use TOSVersion.Check or something?
Remy Lebeau
@rlebeau
GStack.SupportsIPv6
There is currently no GStack.SupportsIPv4, though (in work) to handle the case of IPv6-only systems.
davidpn
@davidpn
that's OK; I'm just after the scenario of where IPv6 is supported
..and thanks
davidpn
@davidpn
The reason is that iOS apps can be rejected if they use IPv4 when IPv6 is available.. I'm looking at using a local patch for IdTCPClient for my own code, but it might be worth considering as in inclusion into Indy
Remy Lebeau
@rlebeau
AFAIK, apps are only rejected if they don't support IPv6-only networks. If a network supports both IPv4 and IPv6, IPv4 is still allowed to be used even though IPv6 is available.
davidpn
@davidpn
do Indy apps switch to IPv6 if that's all that is available?
Remy Lebeau
@rlebeau
As I said before: "not automatically, no". You have to set the IPVersion property manually as needed. Unless you are using Embarcadero's copy of Indy in Seattle or Berlin (I forget which one), in which case it is precompiled to default to IPv6 on iOS.
davidpn
@davidpn
ok.. thanks
fan_tangshan
@sainimu78
blob
A bug in Indy TCP, it losses data!!!
In TIdTCPServer.OnExecute
SetLength(arrBuf, 0);
argContext.Connection.IOHandler.ReadBytes(arrBuf, -1);
OnReceive(@(arrBuf[0]), Length(arrBuf));
In the callback function OnReceive, counts the "Length(arrBuf)", the total number of bytes received. After 10000 times sending, there are about 9000~16000 bytes losed.
fan_tangshan
@sainimu78
In the client app, it sends buffers with random size
blob
Remy Lebeau
@rlebeau
ReadBytes() does not lose data (unless you are performing reads across multiple threads at the same time and corrupting the IOHandler.InputBuffer). You are asking ReadBytes() to return whatever arbitrary bytes are currently available at the time it is being called. However, when AByteCount is -1, ReadBytes() always reads from the socket first, even if there are pending bytes still in the InputBuffer. If there are no new bytes on the socket at that moment, it waits for the IOHandler's ReadTimeout to elapse before then returning whatever is in the InputBuffer. And ReadTimeout is set to infinite by default. So, if there is pending bytes in the InputBuffer, not no new bytes on the socket, ReadBytes() will not return until the next client send. You could check IOHandler.InputBufferIsEmpty() first, and if False then call IOHandler.InputBuffer.ExtractToBytes() directly, otherwise call ReadBytes() instead.
However, that is actually not necessary, because your server code is wrong to begin with. Your client is sending a data packet that has a fixed header on it that includes the data size in it. You server code is completely ignoring that header. You need to have the server read the header, then read the specified number of bytes, then you can pass the completed packet to OnReceive. Then there is no problem.
SetLength(arrBuf, 8); argContext.Connection.IOHandler.ReadBytes(arrBuf, 8); argContext.Connection.IOHandler.ReadBytes(arrBuf, PInteger(@arrBuf[4])^, True); OnReceive(@arrBuf[0], Length(arrBuf));
Remy Lebeau
@rlebeau
Note that you are sending integers in host byte order, which means you are subject to endian differences between the client and server. You really should be using network byte order instead. If you are not going to use the IOHandler's Read/Write methods for integer values, at least use Indy's GStack.HostToNetwork() function before sending the data, and the GStack.NetworkToHost() function after receiving the data, to make sure the integers are in a consistent endian on the wire.
PUInt32(@ sendBuf [0])^ := GStack.HostToNetwork(UInt32(CMDCOMMU_HEADER)); PUInt32(@ sendBuf [4])^ := GStack.HostToNetwork(UInt32(bufsize)); ... PUInt32(@ arrBuf [0])^ := GStack.NetworkToHost(PUInt32(@ arrBuf [0])^); PUInt32(@ arrBuf [4])^ := GStack.NetworkToHost(PUInt32(@ arrBuf [4])^);
Remy Lebeau
@rlebeau
Otherwise, use the IOHandler's reading/writing functions: with cmdClient.fIdClient.IOHandler do begin Write(Int32(CMDCOMMU_HEADER)); Write(Int32(bufsize)); Write(buf); end; ... with argContext.Connection.IOHandler do begin PktType := ReadInt32; PktSize := ReadInt32; ReadBytes(arrBuf, PktSize); end;
fan_tangshan
@sainimu78
@rlebeau Telling me so much, thanks, I will try InputBufferIsEmpty.
Are there simple ways to handle non-fixed size large buffer receiving and to receive buffer with no sticky packs?
Do uses GStack.HostToNetwork to prevent some network device reading error?
Remy Lebeau
@rlebeau
What is the point of putting a fixed header on the packets if your server is not going to use the header for reading the packet? You really shouldn't be doing arbitrary reading in this situation. You know the exact data size up front, so just ask Indy to read that many bytes. Problem solved.
fan_tangshan
@sainimu78
packet splicing
Remy Lebeau
@rlebeau
What are you talking about?
fan_tangshan
@sainimu78
I don't know what it calls, it's just two or more packets received at one time when using TIdTCPServer
Remy Lebeau
@rlebeau
TCP is a byte stream, it doesn't matter if the data is tranmitted on the wire in 1 packet or 100 packets. TCP guarantees reliable delivery. The bytes will be accurate on the receiving end, no matter how many packets it has to read. But, if you want to reduce the number of TCP packets transmitted, you can use Indy's write buffering when sending a packet, eg: with cmdClient.fIdClient.IOHandler do begin WriteBufferOpen; try Write(...); Write(...); Write(...); WriteBufferClose; except WriteBufferCancel; raise; end end;
fan_tangshan
@sainimu78
Then my need is call packet based TCP?
Freq, client sends two times, server gets just one time.
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)