Udp Socket handling - delphi

I want to use UDP Socket to simply send an audio stream. My problem is that i can't get it working i thought it would be simpler then using TCP IP.
What i did i droped a UDPSocket component on my form and for the server part i used this code
with udpServer do
begin
LocalHost := '127.0.0.1';
LocalPort := '5002';
Open();
Active := True;
end;
For the client application this :
with udpClient do
begin
RemoteHost := '192.0.168.100'; //my local address
RemotePort := '5002';
Open();
Active := True;
end;
The problem is i am not receving anything. What i am doing wrong i don't have any third-party software that can block the connection.
I didn't find any suitable example for using this component any source of inspiration will be greatly appreciated.

You have the server and the client connect on the same IP.
Usually if you set the server application IP address to 0.0.0.0 it will bind to any available IP address on the given port, including 127.0.0.1.
Then the client must connect to one of the bound IPs. Instead, you had the server listening on 127.0.0.1 and the client connect to 192.0.168.100.
Don't be fooled by the "LocalHost" property name. "Local" here just mean you have to set a "local" IP, an IP assigned to the local machine, not a "remote" (of another machine) one, while the client of course will connect to a "remote" IP, that of the server.
127.0.0.1 is a good choice if and only if you want your server to be available only to local application, because that IP scope is limited to the same machine. If you want to make it available outside the machine, you have to bind it to a valid IP.
Whatever issue you have, tools like Wireshark or Microsoft Network Monitor are very useful to understand what's going on.

You are binding the server to 127.0.0.1, so it will only accept clients that connect to 127.0.0.1 specifically. Your client is connecting to 192.0.168.100 (perhaps you meant 192.168.0.100?) instead.
You need to bind the server to the IP(s) that clients are actually connecting to, or else bind it to 0.0.0.0 to accept connections on any local IP.
Even though UDP is connectionless, this same rule applies to both UDP and TCP, as it applies to the lower level IP routing layer that they both share.

Related

Correct way to check if my TIdUDPServer is accessible from Internet?

I have created the Delphi application with TIdUDPServer. It listens on a specific port. I forwarded this port on the router programmatically, but I want to make sure my server is accessible from the Internet (from the outside).
Is it correct to use TIdUDPClient with the external IP address (I get it from a special website) and send "hello" to my server, which is in the same application?
I mean, what if the router will return this packet back without actually sending it to the Internet when it will see that the target IP of the packet is its own IP address?

SOCKS 5 Server - BND.PORT & BND.ADDR

In C++ (I didn't include code because this is more of a protocol understanding matter) I am creating a SOCKS5 server and had a few questions because the client terminates the connection after I send it the approved message. In the RFC it says BND.ADDR and BND.PORT are used for: RFC 1928
o BND.ADDR server bound address
o BND.PORT server bound
port in network octet order`
In the reply to a CONNECT, BND.PORT contains the port number that the
server assigned to connect to the target host, while BND.ADDR
contains the associated IP address.
Here are my questions,
What is BND.PORT and what should I specify for it?.
What does it mean by "server assigned to connect to the target host" Is target host the "Client"?
I've read the RFC front to back like 5 times and I have yet to understand it, can someone go into more detail about the BND.PORT and what it means?
I was sniffing around in Wireshark and I found that BND.PORT was different for each request made. (I am not sure what port to enter because everything I tried resulted in Proxifer (The socks client) says "The server gave an unexpected replay - Connection terminated"
Wireshark connection hex-dump from an actual SOCKS5 server (not mine):
Just to make sure we're on the same page... This is the relationship between client, server and host. Notice that the client and host can't talk to each other directly.
CLIENT <-> SERVER <-> HOST
What does it mean by "server assigned to connect to the target host" Is target host the "Client"?
No. The "host" is the device the client is trying to connect to via the SOCKS5 server. The "client" is on the other side of the SOCKS5 server, furthest away from the host.
What is BND.PORT and what should I specify for it?.
BND.PORT is the source port of packets leaving the SOCKS5 server, bound for a host. You have no control over what port the server chooses. Think about it. Where does a host see packets coming from? It certainly isn't the client. From the perspective of the host, packets are all coming from the server, it doesn't know about the client. Additionally the BND.ADDR is the IP of the server.
What I've said is true under the condition that CONNECT is being used. I have no experience with BIND or UDP ASSOCIATE yet.

How to listen and remap tcp connections in delphi?

I have a TCP connection (proxy) that connects through socks4-5 and sends http / https / DNS traffic through it.
I need something to share, something to http / https etc. went through tcp connection 1 and dns resolve through tcp connection 2
I tried to create IdTCPServer1 (But I'm not sure on the right track), it connects but nothing sends him.
In addition, he hangs on until ReadLn it will not be recorded data, and it is not permissible.
procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
var str_str:String;
begin
str_str:=AContext.Connection.Socket.ReadLn();
if(str_str<>'') then Memo1.Lines.Add('#TCP_SERVER: EXECUTE: '+str_str);
You need to handle (implement) the socks4/5 server side protocol (See http://tools.ietf.org/rfc/rfc1928.txt). The in the request, you can intercept to port number to see if it is http, dns or whatever. Then you forward the connection according to it.

Indy TCP Client/Server with the client acting as a server

How can Indy's TIdTCPClient and TIdTCPServer be used in the following scenario:
Client ---------- initate connection -----------> Server
...
Client <---------------command------------------- Server
Client ----------------response-----------------> Server
...
Client <---------------command------------------- Server
Client ----------------response-----------------> Server
The client initiates the connection, but acts as a "server" (waiting for commands and executing them).
The OnExecute approach of TIdTCPServer does not work well in this case (at least I am not getting it to work well). How could I do this?
I hope the question is clear enough.
There is nothing preventing you from doing this with Indy's TIdTCPServer component.
A TIdTCPServer only sets up the connection. You'll need to implement the rest. So the sequence of the actual sending and receiving can be whatever you want.
Put this code in your TIdTCPServer component's OnExecute event:
var
sName: String;
begin
// Send command to client immediately after connection
AContext.Connection.Socket.WriteLn('What is your name?');
// Receive response from client
sName := AContext.Connection.Socket.ReadLn;
// Send a response to the client
AContext.Connection.Socket.WriteLn('Hello, ' + sName + '.');
AContext.Connection.Socket.WriteLn('Would you like to play a game?');
// We're done with our session
AContext.Connection.Disconnect;
end;
Here's how you can setup the TIdTCPServer really simply:
IdTCPServer1.Bindings.Clear;
IdTCPServer1.Bindings.Add.SetBinding('127.0.0.1', 8080);
IdTCPServer1.Active := True;
This tells the server to listen on the loopback address only, at port 8080. This prevents anyone outside of your computer from connecting to it.
Then, to connect your client, you can go to a Windows command prompt and type the following:
telnet 127.0.0.1 8080
Here's the output:
What is your name?
Marcus
Hello, Marcus.
Would you like to play a game?
Connection to host lost.
Don't have telnet? Here's how to install telnet client on Vista and 7.
Or with a TIdTCP Client, you can do this:
var
sPrompt: String;
sResponse: String;
begin
// Set port to connect to
IdTCPClient1.Port := 8080;
// Set host to connect to
IdTCPClient1.Host := '127.0.0.1';
// Now actually connect
IdTCPClient1.Connect;
// Read the prompt text from the server
sPrompt := IdTCPClient1.Socket.ReadLn;
// Show it to the user and ask the user to respond
sResponse := InputBox('Prompt', sPrompt, '');
// Send user's response back to server
IdTCPClient1.Socket.WriteLn(sResponse);
// Show the user the server's final message
ShowMessage(IdTCPClient1.Socket.AllData);
end;
An important thing to note here is that the ReadLn statements wait until there is data. That's the magic behind it all.
If your commands are textual in nature, then have a look at the TIdCmdTCPClient component, it is specifically designed for situations when the server is sending commands instead of the client. The server can use TIdContext.Connection.IOHandler.WriteLn() or TIdContext.Connection.IOHandler.SendCmd() to send the commands.
When the client connects to the server, the server has an OnConnect event with an AContext: TIdContext parameter.
A property of this is AContext.Connection, which you can store outside of that event (say, in an Array). If you pair it with the IP or better yet a generated Session ID, then reference that Connection by that criteria, you can then have the server send adhoc commands or messages to the client.
Hope this helps!
normally the client and the server side have a thread that is reading incoming telegrams, and sending pending telegrams...but this kind of protocols (send/receive, when and what) depend of the application.
A very good starting point how the client side can be implemented using a thread, listening for messages from the server, is the Indy Telnet client component (TIdTelnet in the Protocols folder).
The Indy telnet client connects to the telnet server and uses only one socket to write and read data. Reading happens in a listener thread.
This design can easily be adapted to build distributed messaging software like chat etc., and also shows how easy the protocol can be decoupled from the network layer using blocking sockets.
With Indy this is not possible by design:
Indy supports only Client-initiated communication, what means the server can only send a response to requests by the client.
The easiest way (but not the smartest) to get what you want is to use a pull-process. Controlled by a timer the clients ask the server if there is a new command. Of course this will cause a lot of traffic-overhead and depending on your pull-intervall there is a delay.
Alternatively you could use another library like ICS (http://www.overbyte.be/eng/products/ics.html)

several UDP sockets, bound to same port?

first - it's not a question of "how to bind to port of another software".
now, i have a client-server app, based on TCP and i'd like to make it UDP, but i'm missing something..
i have 2 rules (which i put) to this app:
1) the "server" can stay behind router without any port forwarding configuration.
2) the "client" can listen to only one port.
in TCP i do it like this:
1) the server opens initial connection to the client on port X.
2) when the client wants to open communication channel to the server it uses the initial socket to ask the server for a new one.
3) the server creates a new socket and connect to the client on port X.
4) the client accept this new connection on port X, and now the client talk with the server on this new socket.
this way i can have multiple connections on the same port.
in UDP, i have a little problem..
1) the server sends the initial connection dgram to the client on port X.
2) when the client wants to open communication channel to the server it sends request for a new socket to the initial socket's addr.
3) the server receives the message, creates a new udp socket, and use it to send data to the client on port X.
4) the client receives the new dgram, and ....?
basically what i want to happen now is to "accept" this connection. meaning: to create a new UDP socket, to bind it also to port X and receive data only from that specific incoming socket addr (ip,port). but i cannot do that because i can't bind multiple socket to same port.
so what is the way to create multiple udp connections on one port? (in networking way, not just create a ring buffer of dgrams and send to the right socket)
thanks :)
As UDP is connectionless protocol, on step 4 you check the contents of UDP message and decide how to handle it. In other words, the type of message is defined only by it's contents.
However, I have a feeling that your whole design is a bit wrong. It's much more common for the client to be behind firewall (just because there exist more clients, than servers). If you need to put the server behind firewall, you just configure the firewall to allow connections to the set of ports. Even when you have just one more port opened, nothing prevents the client from connecting to the same server port several times in parallel.

Resources