Jump to content

Remy Lebeau

Members
  • Content Count

    2333
  • Joined

  • Last visited

  • Days Won

    94

Everything posted by Remy Lebeau

  1. Remy Lebeau

    Embed Signature Resource in email

    Addressed in this discussion thread.
  2. Remy Lebeau

    Sending Email via GMail Using OAuth 2.0 via Indy

    If you use the TIdMessageBuilder... classes, such as TIdMessageBuilderPlain or TIdMessageBuilderHtml (https://www.indyproject.org/2008/01/16/new-html-message-builder-class/), they will populate the TIdMessage for you. If you populate the TIdMessage manually, then yes, you are responsible for populating it correctly (ie https://www.indyproject.org/2005/08/17/html-messages/).
  3. Remy Lebeau

    AnsiString oddities

    All string classes in C++Builder - the RTL's (Ansi|Unicode|Wide)String classes, the Standard Library's std::(w|u8|u16|u32)string classes, etc - have concatenation methods built-in. The main reason for using a StringBuilder is memory management (being able to preallocate a buffer and then performing multiple concatenations into it), and that really only applies to RTL strings, as Standard Library strings have a reserve() method for that same purpose. Also, the standard C++ alternative to a StringBuilder is the std::(w)istringstream classes.
  4. Remy Lebeau

    AnsiString oddities

    Don't feel bad. Until about a year ago, I was still regularly using C+++Builder 6 at my day job. Why are you concatenating a WIDE string literal to an ANSI string? You should drop the 'L' prefix, it doesn't really belong there. AnsiString doesn't have an operator+= that takes a Unicode string as input, only another AnsiString. So you are actually invoking the AnsiString constructor that accepts a Unicode string, and that is forcing a Unicode->ANSI data conversion at runtime, which you don't need. The code looks fine, provided that the Form1 pointer is valid to begin with, otherwise the code would have undefined behavior. Yes, you should, provided everything is valid. Have you tried displaying the AnsiString anywhere other than in a debug inspector? Have you tried showing it in your app's UI? Or in a popup MessageBox? Or save it to a file? Anything? That is what the debugger is meant for. Step through the code at runtime line by line, and actually step into the internal logic of the assignment and concatenation operations to make sure they are doing what you are expecting. The only way I could imagine that happening is if either the Form1 pointer is invalid during the assignment, or if the debugger is broken. Which do you think is more likely?
  5. Remy Lebeau

    Sample needed for Net.TSocket UDP cliente and server

    Just because it runs is in a thread doesn't guarantee it is fast/efficient. And actually, in your scenario, there is actually an interrupt, see below... I just now gave it a quick look, and one major issue I see is that you are not using TIdUDPServer the way it is meant to be used, You are creating it in your own thread that does its own reading of the UDP socket, rather than using TIdUDPServer's OnUDPRead event. It seems you are not aware that TIdUDPServer is a multi-threaded component, its OnUDPRead event is fired in the context of internal reading threads, one per Binding. The Synapse/Net.TSocket UDP sockets you are using don't work that same way. So, it actually makes sense now why you are losing packets when using Indy - your code has multiple threads reading from the same UDP socket at the same time, so there are going to be times that you will receive packets in your own thread and be able to process them, and there are going to be times when TIdUDPServer will receive packets that you are ignoring. If you want to do your own reading of an Indy UDP socket, don't use TIdUDPServer, use TIdUDPClient instead. Despite their names, they are not truly client/server components, like with how TCP components work. Since UDP is connection-less, you can actually mix TIdUDPClient and TIdUDPServer in various ways. You can use TIdUDPServer as a client and TIdUDPClient as a server. Or you can have two TIdUDPClients, or two TIdUDPServers, communicate with each other. The difference between them is only in how they manage their respective sockets internally. With TIdUDPClient, it just creates the socket, but you are responsible for all of the reading/writing. With TIdUDPServer, it does all of the reading for you, and then you are responsible for writing. That being said, I see a secondary issue in your code, not related to any particular socket library, that could also cause packet loss. In your reading thread, when you do receive a packet, you lock a TCriticalSection before processing the packet. But, you are using TCriticalSection.TryLock() for that lock, which is not a blocking function. If, for some reason, the CS is already locked by another thread, TryLock() will exit immediate with a False return value, and you will then skip processing the packet, you are not caching/retrying the packet, you just throw it away. There is actually 2 buffers involved - the kernel buffer inside the socket itself, and the application buffer that TIdUDPServer reads into before giving you the data in the OnUDPRead event. To set the size of the socket's buffer, you can use Indy's TIdSocketHandle.SetSockOpt() method to assign a value to the socket's SO_RCVBUF option. To set the size of the OnUDPRead buffer, TIdUDPServer has a BufferSize property, which defaults to 8K.
  6. Remy Lebeau

    Using Resource in Email

    According to the timestamps of the posts, you posted this topic here at 2021-12-17 14:17:34Z, and posted on StackOverflow at 2021-12-17 14:21:24Z. Same day, 4 minutes apart.
  7. Remy Lebeau

    Opinions about Pascal vs C/C++ IDE

    Yes. There are MANY solutions available for cross-platform development. There is FreePascal, for instance. Or Java. Or many other choices. Not really. It is up to you to decide. You know what you need. Use what suits your needs. Every language and IDE has advantages and disadvantages. Do some research on each one then decide for yourself. It depends on the platform, and what degree the OS allows you to directly access hardware. Most direct hardware access on modern systems is restricted to just the OS, so you would have to use higher level APIs provided by the OS or the hardware vendor. No. Pascal can get just as low level as C/C++ can get.
  8. Remy Lebeau

    Using Resource in Email

    You posted your question on this forum at 14:17:35Z, then you posted on StackOverflow at 14:21:24Z. That is a difference of only 4 MINUTES. These are NOT real-time forums. You have to give people TIME to answer. Personally, I didn't see your questions on either forum until 3 HOURS after you had posted them. Sometimes it can take people DAYS to answer. So please be patient. Also, it is generally considered rude to ask the same question on multiple forums at the same time. It means you consider other people's time less important than your own ("I posted here, but I'm not going to wait around for a response, I'm going to go over there instead").
  9. Remy Lebeau

    Using Resource in Email

    You asked this exact same question on StackOverflow, and received answers there: https://stackoverflow.com/questions/70394569/delphi-using-resource-in-email-rather-than-image
  10. Remy Lebeau

    Sending Email via GMail Using OAuth 2.0 via Indy

    TIdMessage creates RFC822-style emails. Do note, however, that the TIdMessage.SaveTo...() methods are designed for SMTP usage, and so will escape emails per SMTP dot-transparency guidelines. So, to use TIdMessage emails in other protocols, be sure to use the overloaded SaveTo...() methods provided by the TIdMessageHelper unit, which adds an AUseDotTransparency parameter that you can set to False to disable that escaping. https://www.indyproject.org/2015/07/30/new-tidmessage-helper/
  11. Remy Lebeau

    Sending Email via GMail Using OAuth 2.0 via Indy

    No, unless you do it yourself manually. You are simply using the wrong tool for the job to begin with. TIdMessage is designed for email only, not for HTTP posts. There is nothing in Indy that specifically handles the Gmail REST API you are referring to, so you are going to have to implement it yourself.
  12. The new overloads were added, and the original overloads were deprecated, in XE3.
  13. Remy Lebeau

    Indy Documentation Problem

    Known issue, not fixed yet: https://www.indyproject.org/2021/02/10/links-to-old-indy-website-pages-are-currently-broken/
  14. Remy Lebeau

    Sample needed for Net.TSocket UDP cliente and server

    I agree with @Fr0sT.Brutal. UDP is an unreliable connectionless transport, so some amount of packet loss is to be expected, even over a direct cable. The most common cause of packet loss is when the receiver is reading packets slower than they are being sent and so it runs out of buffer space. Until buffer space is freed up, new packets will get silently discarded by the OS. So, check if your reading code is running too slow, or that your receive buffer is too small for your situation. Of course, there can be other causes of packet loss, too (network congestion, outages, etc).
  15. Remy Lebeau

    Another case of tlsv1 alert protocol version

    I can't address that without seeing the actual TLS handshake in a working scenario vs a non-working scenario. All that tells me is that your XE is either not actually upgraded to the same Indy version that 10.4 is using, or your XE project is not configured the same way as the 10.4 project. Neither do I. AFAIK, yes.
  16. Remy Lebeau

    Another case of tlsv1 alert protocol version

    Then you still have old files lingering somewhere. Or maybe the new LSP server hasn't parsed the newer files. I don't know. It has been a long time since I last did an upgrade. Try using a tool like SysInternals Process Monitor to see what files the IDE is actually touching as it is loading/compiling, maybe you will see something out of place. If you are referring to the DFMs, then probably not. But it probably wouldn't hurt either, as there have been some declaration changes to properties/events over the years, depending on which components you are using. There should have been dcl files produced, too, since those are part of the design-time packages that get installed on the IDE's Palette. Embarcadero doesn't use the default DPK projects to compile the shipped version of Indy. They use their own DPKs, for instance to enable the use of {$LIBSUFFIX}, which Indy hasn't adopted yet, but will eventually. So, getting 5 DCPs with suffixes in their names is expected behavior, albeit not ideal behavior for modern IDEs. Having the suffixes present only becomes an issue when you upgrade between major IDE versions, then you need to update any projects that refer to the suffixed DCPs. LIBSUFFIX was introduced WAY back in Delphi 6 to avoid that. That really won't work when communicating with modern servers on the Internet. SSL v2.0 and v3.0 are dead, nobody using them anymore. And TLS v1.0 is fast being phased out. You really need TLS v1.1 and v1.2 to communicate with current servers, with TLS v1.3 slowly being adopted, too.
  17. Remy Lebeau

    Long term availability of Community Edition

    I would not call it a "short" delay. It is actually a considerable delay. I can't find exactly when 10.3 CE was released, but 10.2 CE was released 16 months after 10.2 was released, and 10.4 CE was released 14 months after 10.4 was released. Now 11.0 was released 3 months ago and we are going to wait how long for a 11.0 CE release? They tend to release a new CE either after several Updates have been released first, or just-before/long-after the next major version release. Also, it should be noted that even when a new CE version is not released, the CE license expires annually, so you have to keep reinstalling the latest CE every year to continue using it.
  18. Remy Lebeau

    Another case of tlsv1 alert protocol version

    Then you are using a VERY old version of Indy and really should upgrade to the latest. Most likely NOT 10.6.2.0 specifically, but some later version of 10.6.2.x, where x was unknown at the time your copy of Indy was compiled. Specifying multiple SSL/TLS versions will automatically enable sslvSSLv23 internally. That is the wildcard that actually handles version negotiation at runtime. You should not be specifying sslvSSLv23 explicitly at all. Makes sense, because nobody uses SSL v2.0 and v3.0 anymore, as they are no longer secure. Don't use anything less than TLS v1.0, but even that is being phased out of modern servers nowadays, so you really need TLS v1.1 and v1.2 as an absolute minimum. If that weren't the case, the other values (sslvSSLv2, sslvSSLv3, sslvSSLv23, and sslvTLSv1) wouldn't be compiling, either.
  19. Remy Lebeau

    Simple JSON parsing

    If you catch a socket exception and discard it, you don't know on WHICH BYTE the exception was raised on, so how do you expect to recover your communications from that? In general, DON'T discard any exception you can't recover from. If you need to act on an exception (ie, to log it, etc), then catch it, but you should re-raise it when finished. Only discard exceptions you can recover from (socket exceptions are rarely ever recoverable, since the I/O state is typically dead/invalid at that point). The most common reason for that (but certainly not the only reason) is when a deadlock occurs while a server thread is performing an operation that is synchronized with the same thread that is trying to deactivate the server. For instance, trying to update the UI from a server thread while the UI thread is blocked waiting on the server to close. Possibly, yes. Indy relies on exceptions for error reporting, and certain exceptions, particularly socket-related ones, are important to tell the server when a client connection has been closed and its managing thread should stop running. So, if you just blindly catch and discard exceptions, the server might not shut down properly. So, at the very least, if you catch any exception that is derived from EIdException, re-raise it, let the server handle it.
  20. Remy Lebeau

    Simple JSON parsing

    That is an unusual thing to do. This is really no better than a try..finally: try ... finally // sends response as json contents Connection.IOHandler.WriteLn(Response); end; But, what if it is the last WriteLn() that raises the exception? Then you try the same WriteLn() again? I would use this instead: try ... finally try // sends response as json contents Connection.IOHandler.WriteLn(Response); except end; end; Though, are you really sure you want to catch an exception at all? You are going to leave the connection in an unstable state. You may as well just let the exception propagate up the call stack uncaught, and let the server catch it and close the connection for you.
  21. Remy Lebeau

    SAX parser

    For XML? You could try using libxml2 (http://xmlsoft.org), which is a free cross-platform C-based XML parser that has both SAX and DOM APIs, and offers bindings for Pascal.
  22. Remy Lebeau

    Another case of tlsv1 alert protocol version

    Don't include sslvSSLv23 with other versions, that is a wildcard the IOHandler uses internally, it is not needed in this case. Also, you definitely should not include sslvSSLv2 and sslvSSLv3 at all (unless you really need them), as those are old and no longer secure. Typically, you should include only the TLS versions: LHandler.SSLOptions.SSLVersions := [sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2];
  23. Remy Lebeau

    Simple JSON parsing

    Note that you are responsible for freeing the TJSONValue returned by ParseJSONValue(), so you should use a try..finally for that: // parse json JSONValue := TJSONObject.ParseJSONValue('{"cmd":"program.add.text", "txt":"for I := 0 to 100 do"}'); try if not (JSONValue is TJSONObject) then Exit; ... finally JSONValue.Free; end;
  24. Remy Lebeau

    How can I use nslookup in my app.

    Nitpicking: You are leaking every TIdHTTP object you create. You are querying an HTTPS URL, but you are not assigning any SSLIOHandler object to the TIdHTTP.IOHandler property. While TIdHTTP can create a default SSLIOHandler object for you, just note that it only supports TLS 1.0 right now. So, if you ever need to update your code to handle TLS 1.1 or 1.2, you are going to have to assign the TIdHTTP.IOHandler manually. Your FormCreate() is requesting the URL twice. You already have the text from the 1st query saved in your compare variable, so just assign that variable as-is to your TMemo, you don't need to query the URL again until the TTimer elapses. Your Timer is logging when the IP does not change, but does not log when it does change, or what the new IP is.
  25. Remy Lebeau

    DLL without underscore mangled functions

    When exporting your own functions, simply don't mark your original function as being exported from code (via either __declspec(dllexport) or __export), let the DEF file handle the exporting, so you control the format of the mangling. But, for library functions, I don't think you can do this.
×