I am new to Apache Thrift and was playing around with the toy Delphi client server example that Apache provides here: https://thrift.apache.org/tutorial/delphi
We've made some minor changes to names and to how the port and IP is set up, but basically identical otherwise.
In the server we have the following code:
PORT := StrToInt(ParamStr(1));
handler := TPhraseGeneratorHandler.Create;
processor := TPhraseGenerator.TProcessorImpl.Create( handler);
transport := TServerSocketImpl.Create( PORT);
server := TSimpleServer.Create( processor, transport);
WriteLn( 'Starting the server on port ' + PORT.ToString + '...');
server.Serve();
In the client we have the following code:
var transport : ITransport;
protocol : IProtocol;
client : TPhraseGenerator.Iface;
phraseRequest : IPhraseRequest;
// Let the user pass in the parameters for host and port
HOST : String;
PORT : Integer;
begin
try
// Open a connection to the server using the host and port supplied by the user
HOST := ParamStr(1);
PORT := StrToInt(ParamStr(2));
WriteLn('Openning a connection to the server: ' + HOST + ' on port: ' + PORT.ToString);
transport := TSocketImpl.Create( HOST, PORT, 10000); // specifically add a timeout as our test server deliberately goes to sleep for 5000ms
protocol := TBinaryProtocolImpl.Create( transport);
client := TPhraseGenerator.TClient.Create( protocol);
transport.Open;
If we open the client and server on the same machine and use 'localhost' we can get them to communicate.
If however we open them on different machines and specify the server's ipv4 address we cannot.
Using netstat we get the following:
D:\Temp>netstat -ano | findstr 9090
TCP [::]:9090 [::]:0 LISTENING 15368
Which I think indicates that the server is only listening on ipv6.
Q: Am i correct? and if so how can we get it to listen on ipv4?
I'd say that you are 100% correct.
The relevant section from CreateSocket()
:
// Pick the ipv6 address first since ipv4 addresses can be mapped
// into ipv6 space.
Res := Result.Res;
while Assigned(Res) do begin
if (Res^.ai_family = AF_INET6) or (not Assigned(Res^.ai_next)) then
Break;
Res := Res^.ai_next;
end;
FSocket := Winapi.Winsock2.socket(Res^.ai_family, Res^.ai_socktype, Res^.ai_protocol);