How do I use TIdTelnet to send commands? - delphi

I am trying to simulate the "new identity" button in Vidalia (the Tor GUI) from my program. I asked about that, based on Rob Kennedy's answer, I tried this in my application:
IdTelnet1.Host:='127.0.0.1';
IdTelnet1.Port:=9051;
IdTelnet1.Connect(-1);
IdTelnet1.SendCmd('SIGNAL NEWNYM');
But it has not worked for me. Even after I send the command, I get the same proxy.
I am using Indy 9.
I don't know whether I don't know how to use TIdTelnet or don't know how to send that specific command.

You cannot use the SendCmd() method with TIdTelnet. TIdTelnet uses an internal reading thread that continuously reads from the socket (since Telnet is an asynchronous protocol that can receive data at any time). SendCmd() does its own internal reading to receive the sent command's response. The two reading operations interfer with each other (this issue also exists in Indy 10's TIdCmdTCPClient component for the same reason).
To send an outgoing command with TIdTelnet, you must use its SendCh() method to send each character individually (if you upgrade to Indy 10, TIdTelnet has a SendString() method whch handles that for you) and then wait until the OnDataAvailable event to process the response as needed.
Unless TOR is actually using the real Telnet protocol (Telnet sequences and all), then you are better off using TIdTCPClient instead of TIdTelnet. TIdTelnet is a Telnet-specific client, not a general purpose TCP/IP client like TIdTCPClient is.

Related

How can I avoid freezing on Write to socket in Indy if the other end is not reading data from the Socket

I have a application with client and server sockets using Indy, compiled with Delphi 10.2.
The application have a working thread that processes requests from the different ports and write responses within the same thread using a call to something like this:
procedure TMyCommManager.WriteResponse(AHandler: TIdIOHandler; SomeData: SomeType);
var
idBytes: TidBytes;
PacketSize: Integer;
begin
SomeData.GetBytes(idBytes, PacketSize);
AHandler.Write(DataBuffer, PacketSize);
end;
Almost all the time everything is working as expected, but we noticed the worker thread is freezing from time to time in production. After various iterations, we finally got to the point that all this is occurring in the call to the TidIOHandler.Write() and I'm quite sure it is happening because the other end for a single port is not reading the responses from the socket.
After a reset to the port from within the other end the worker thread unfreezes and keeps working as expected.
I found this answer from Remy Lebeau to the question Delphi (Indy) Server Freezing on Write, where he mentions in comments (emphasis mine):
Indy uses blocking sockets, so if the client is not reading inbound data on its end, eventually the socket's internal send buffer will fill up and the socket will become blocked on the server side waiting for the client to empty the buffer. The only way to avoid a deadlock in that scenario would be to set a socket-level send timeout using the socket API directly. Indy does not implement send timeouts in its logic.
I'm looking for the correct way to set that timeout, via INDY or via a direct API call in Windows, but I'm stuck in that, so I come here looking for help.
If that's not possible, I could implement a Timeout mechanism on a secondary thread, but I'm not sure what's the correct way to reset the connection from this secondary thread on my end to let the worker thread continue it's work.
I'm looking for the correct way to set that timeout, via INDY or via a direct API call in Windows
In my previous comment, when I said "set a socket-level send timeout using the socket API directly", I was refering to the SO_SNDTIMEO socket option via the setsockopt() function.
In terms of Indy, you can call setsockopt() by using the TIdSocketHandle.SetSockOpt() method, eg:
// Windows
SomeConnection.Socket.Binding.SetSockOpt(Id_SOL_SOCKET, Id_SO_SNDTIMEO, TimeoutInMS);
// 'Nix
var tv: timeval;
...
SomeConnection.Socket.Binding.SetSockOpt(Id_SOL_SOCKET, Id_SO_SNDTIMEO, Integer(#timeval));
or:
GBSDStack.SetSocketOption(SomeConnection.Socket.Binding.Handle, Id_SOL_SOCKET, Id_SO_SNDTIMEO, timeval, sizeof(timeval));
(the TIdTCPConnection.Socket property is a shorthand for accessing TIdIOHandlerSocket when the TIdTCPConnection.IOHandler has been assigned a TIdIOHandlerSocket or descendant).
Just know that if a timeout does occur, you can't know exactly which data was actually transmitted to the peer, so recovery is usually impossible in most protocols. All you can really do is just close the connection and reconnect.

Two-way TCP communication in Indy 10?

I am using TIdCmdTCPClient and TIdCmdTCPServer. Suddenly I find that I might like to have bi-directional communication.
What would be best? Should I possibly use some other components? If so, which? Or should I kludge and have the 'client' poll the 'server' to ask if it wishes to communciate anything?
This is a very small system. Two clients and ten servers, with a burst of one tarnscation every 30 to 60 seconds for a few minutes once a day, so overhead for polling is inconsequential.
I'm just woder if there is a 'correct' way.
Update: this really is an incredibly simple system. Very little traffic and all of it simple. All transmissions are an indication of even type an an optional single parameter.
<event type> [ <parameter>] e.g. "HERE_IS_SOME_DATA 42"
This can be sent in both directions, hover here is no "reply" as such. Just fire off a message (and hope that it got there)? Receive an Ack with no data? Non-catching of an exception indicates that message was successfully sent?)
Would it be possible (would it be overkill) to use two TIdCmdTCPServer?
Both TIdCmdTCPClient and TIdCmdTCPServer continuously poll their socket endpoints for inbound data during the lifetime of the connection. You do not have to do anything extra for that. So, as soon as a TIdCmdTCPClient connects to the TIdCmdTCPServer, both components will initially be in a reading state until one of them sends a command to the other.
Now, there is a problem with doing that - as soon as either component sends that first command, the receiving component will interpret it as a command and send back a reply, which the other component will interpret as a command and send back a reply, which will be interpretted as a command and send back a reply, and so on, causing an endless cycle of replies back and forth. For that reason, it is not wise to use TIdCmdTCPClient and TIdCmdTCPServer together. You should either use TIdTCPClient with TIdCmdTCPServer, or use TIdCmdTCPClient with TIdTCPServer. Depending on what exactly your protocol looks like, you may have to forgo using TIdCmdTCPClient and TIdCmdTCPServer altogether and just use TIdTCPClient with TIdTCPServer so you have more control over reading and writing on both ends. It is hard to answer with actual code without first knowing what the communication protocol should look like.
A single TCP socket connection can be used in two directions. The server can send data asynchronously to the client at any time. It is up to the client however to read the socket, for asynchronous processing this is done in a listener thread which reads from the socket and synchronizes incoming data operations with the main worker thread.
An example use case in the Indy components is the Telnet client component (TIdTelnet) which has a receive thread listening for server messages.
But you also asked about the 'correct' way - and then the answer depends on other factors such as network stability, guaranteed delivery and how to handle temporary server outages. In enterprise environments, one central messaging hub is preferred in many use cases, so that all parties connect only to this central server which is only responsible for reliable message delivery, and keeps messages until the recipient is available.
You can download the INDY 10 TCP server demo sample code here.

Sending and receiving data streams in Delphi

I want to create a software to connect to another and send some data (text based) to another program through the internet.
The software will send data every 300 milliseconds (using timer) and the receiver must receive the data on time.
The connection can be like the following
any data can be lost;
but the rest must arrive on time with minimum delay as possible (maximum 2 seconds);
the delayed data can be considers as lost, can be ignored.
I think it may be similar to a video conference software, but only using simple text as data.
Can anyone tell me how to make such a program, specifically
what kind of component can I use (any INDY examples);
what technologies do you recommend.
I have planned to do it with Delphi but other recommendation also welcome .
==========================update1 =================
Is it possible to send images through the stream
I suggest using UDP protocol and adding timestamp information to your data and track incoming data on the receiving end. You can use UDP server (TIdUDPServer) and client (TIdUDPClient) components from Indy or other packages. Client component is for sending data and server for receiving.
Personally I usually prefer Synapse -classes. They are lower level than Indy, so it's easier to know what's happening but on the otherhand you may need to implement something yourself what Indy may provide by default.
Update
Implementation is pretty straight forward:
Sending data:
Drop TIdUDPClient on the form. Set "Host" to name or IP address of receiving end (or "localhost" if you run your programs in same computer) and port to high number where server is listening, eg 54656.
Add following code to button or timer event:
IdUDPClient1.Send('Hello, world!');
Receiving data:
Drop TIdUDPServer component on the form. Set default port to same port as in sending application. Add OnUDPRead event handler, with code:
MessageDlg('Received: ' + StringOf(AData), mtInformation, [mbOk], 0);
And new message dialog pops up everytime new message is received.
Update 2
UDP is not good for images, if you want to be sure they will stay uncorrupted, unless the image is very small and fits inside one packet.
I'd recommend using anything but Indy. It is both buggy (especially versions bundled with Delphi) and slower than other component sets. It is easy to understand and start using it, but once you delve deeper under the hood, you start noticing small problems. Indy is constantly under development and you can find latest build here. Problem is that you can't easily replace the bundled version with newer in Delphi versions from 2009 onward because of some hard-coded dependencies.
Delphi has few other network communication methods integrated, but I recommend exploring 3rd party components. First, if you want open source, you should take a look at Overbyte ICS. It is a bit difficult to master, but it has good performance and feature set.
As a very good commercial solution, take a look at IP^Works. I have only scratched it, but from what I saw, I can wholeheartedly recommend it.

Which is more appropriate for pbx events, TIdTCPServer or TIdTCPClient?

I am trying out some IP PBX systems, Asterisk, Freeswitch, and Yate,to register for events in the PBX, and I want to know which of these components is the better one.
The component is supposed to register with the PBX for events, receive them, send some responses and issues some commands. Which of the two would be the more appropriate?
The difference between a TCP server and client is who initiates the connection. The client connects to the server. So I'm guessing you should use the TIdTCPClient.
Asterisk has a well-defined network TCP/IP event-driven protocol which supports SSL communications. This module is called the Asterisk AMI, and is widely used to do exactly what you want.
You can read the documentation on the AMI here: http://www.voip-info.org/wiki/view/Asterisk+manager+API
Also, if you want to check out some products which use the AMI events as their core product, check out:
Flash Operator Panel http://www.fop2.com/
HUD http://www.fonality.com/products/hud
Asterisk Assistant http://blogs.digium.com/2008/12/22/asterisk-desktop-assistant-windows-click-to-call-and-more/
Enjoy :)
Another option would be to use Synapse which is a blocking TCPIP library which is very easy to use and supports free pascal, as well as Delphi.

Delphi Network programming

I have a classic client/server (fat client and database) program written in Delphi 2006. When certain conditions are met in the client, I need to notify all the other clients very quickly. Up until now this has been done using UDP broadcasts, but this is no longer viable as clients now connect from outside the LAN and the UDP broadcast is limited to the local network.
I'm aware of the Indy libraries but am not really sure of which components to use and how to structure it. I'm guessing I'll need to have a server that the clients connect to which will receive and distribute the messages...? Any samples out there to get me started?
Are there any other component sets or technologies I should look at instead/as well?
The simple answer is that the standard protocols available in Delphi (and other tools) don't allow for notification in reverse. I looked into this for a project where I wanted to use SOAP. They all assume client asks server, server responds and that's it.
For me, the solution was the RemObjects SDK. This allows you to send notifications to clients, and the notification can have any data you like (just like the client to server). Myself I use the SuperTCP connection, but it works with others too. It can still offer a SOAP interface for clients that must use it, but for where you have control of both client and server it works extremely well.
There are a few really easy ways to do this with Delphi, although I am sure the RemObjects SDK works really well too.
Have a central server that has a * TIdTCPServer listening* on it. Then each client has a TIdTCPClient on it. They connect to the server and block on a read waiting for the server to write. Once the server receives a notification via a listening socket it broadcasts to each of the waiting clients. This is pretty much immediate notification of all the clients.
Have a central server that has a TIdTCPServer listening on it. Then each client has a TIdTCPClient on it. Those clients can "ping" the server to ask for updates at a regular interval (use a session token to maintain state). The frequency of the interval determines how quick the notification will be. When once one of the clients needs to notify the others, it just notifies the server. The server then uses a message queue to make a list of all active client sessions and adds a notification for each. Then the next time each of the clients connects it gives it the notification and remove it from the queue.
Maintain a session table in the database where each client updates regularly that they have an active session, and removes itself when it disconnects. You will need a maintenance process that removes dead sessions. Then you have a message queue table that a client can write an update to with one row for each current active session. Then the other clients can regularly ping that table to see if there are any pending notifications for its session, if there are it can read them, act on them and then remove them.
Some sort of peer to peer approach were the clients are aware of each other through information in the database and then they connect directly to each other and notify or ask for notifications (depending on firewall and NAT configurations). A little more complex, but possible.
Obviously the choice of implementation will depend on your setup and needs. Tunning will be necessary to achieve the best results.
The components you need for this are the TIdTCPServer (listener) and TIdTCPClient (sender). Both of which are in the Indy libraries in Delphi.
ICS components from http://www.overbyte.be are great.
a.) Better compatibility than Indy
b.) PostCard ware
Good examples and support. Use TClientSocket and TServerSocket
FirebirdSQL project use the concept of notifications as being server-client connections that send a string to the client. For this, the db server uses an other port. And require the client to register it's interesting of receiving a certain type of notification through an API call.
You could use the same idea.
RabbitMQ should fit your bill. The server is free and ready to use. You just need a client side to connect, push/send out message and get/pull notified message
Server: http://www.rabbitmq.com/download.html
Do a google for client or implement yourself
Cheers
You should be able to use Multicast UDP for the same purpose. The only difference will be to join the multicast group from every client.
http://en.wikipedia.org/wiki/IP_Multicast
http://en.wikipedia.org/wiki/Internet_Group_Management_Protocol
Edit: Just to clarify, multicast let you join a given "group" associated to a multicast ip address. Any packet sent to that address will reach every client who has join the group
You can watch weonlydo wodVPN component which permit you to create a robust UDP hole punching and gain a port-forwading or a normal VPN (with a fornished network adapter) so you can connect two PC behind a NAT.
I'm using this control for our communication program and works very fine.

Resources