Delphi (我认为)Thrift server只监听ipv6

Delphi (我认为)Thrift server只监听ipv6,delphi,thrift,Delphi,Thrift,我是Apache Thrift的新手,在这里玩Apache提供的toy Delphi客户机服务器示例: 我们对名称以及端口和IP的设置方式做了一些小改动,但在其他方面基本相同 在服务器中,我们有以下代码: PORT := StrToInt(ParamStr(1)); handler := TPhraseGeneratorHandler.Create; processor := TPhraseGenerator.TProcessorImpl.Create( handle

我是Apache Thrift的新手,在这里玩Apache提供的toy Delphi客户机服务器示例:

我们对名称以及端口和IP的设置方式做了一些小改动,但在其他方面基本相同

在服务器中,我们有以下代码:

    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();
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;
在客户端中,我们有以下代码:

    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();
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;
如果我们在同一台机器上打开客户机和服务器并使用“localhost”,我们可以让它们进行通信

但是,如果我们在不同的机器上打开它们,并指定服务器的ipv4地址,我们就不能

使用netstat,我们可以得到以下结果:

D:\Temp>netstat -ano | findstr 9090
  TCP    [::]:9090              [::]:0                 LISTENING       15368
我认为这表明服务器只监听ipv6

问:我说得对吗?如果是这样的话,我们怎样才能让它在ipv4上监听呢

CreateSocket的相关部分:

我可以这么说

CreateSocket的相关部分:

更新 我们已经找到了如何编辑Delphi节约代码以允许ipv4。在这里发布,以防对其他人有所帮助

相关的过程是过程TServerSocket;在文件Thrift.Sockets.pas中

:

:

更新 我们已经找到了如何编辑Delphi节约代码以允许ipv4。在这里发布,以防对其他人有所帮助

相关的过程是过程TServerSocket;在文件Thrift.Sockets.pas中

:

:


如果你对@JensG,upgdate Belowwin感兴趣,你对@JensG,upgdate belowGreat感兴趣!是否可以发送拉取请求?出于法律原因,我不能自己拿着代码去做。但我可以查看并合并拉取请求。-伟大的是否可以发送拉取请求?出于法律原因,我不能自己拿着代码去做。但我可以查看和合并拉取请求-
var
  TempIntReader,
  TempIntWriter: Winapi.Winsock2.TSocket;
  One: Cardinal;
  ErrnoCopy: Integer;
  Ling: TLinger;
  Retries: Integer;
  AddrInfo: IGetAddrInfoWrapper;
  SA: TSockAddrStorage;
  Len: Integer;

  // ### ADD THIS ###
  Zero: Cardinal;
  // ### END ADD ###
// Set SO_EXCLUSIVEADDRUSE to prevent 2MSL delay on accept
  One := 1;
  setsockopt(Socket, SOL_SOCKET, Integer(SO_EXCLUSIVEADDRUSE), @one, SizeOf(One));
  // ignore errors coming out of this setsockopt on Windows.  This is because
  // SO_EXCLUSIVEADDRUSE requires admin privileges on WinXP, but we don't
  // want to force servers to be an admin.

  // ### ADD THIS ###
  // set IPV6_V6ONLY=0 so that the server uses dualstack sockets
  // i.e., we will get both IPv6 and IPv4-mapped IPv6 connections on the same socket
  // (ignore errors)
  Zero := 0;
  setsockopt(Socket, IPPROTO_IPV6, {IPV6_V6ONLY}27, @Zero, SizeOf(Zero));
  // ### END ADD ###

  // Set TCP buffer sizes
  if FTcpSendBuffer > 0 then begin
    if setsockopt(Socket, SOL_SOCKET, SO_SNDBUF, @FTcpSendBuffer, SizeOf(FTcpSendBuffer)) = SOCKET_ERROR then begin
      ErrnoCopy := WSAGetLastError;
      LogDelegate(Format('TServerSocket.Listen() setsockopt() SO_SNDBUF %s', [SysErrorMessage(ErrnoCopy)]));
      raise TTransportExceptionNotOpen.Create(Format('Could not set SO_SNDBUF: %s', [SysErrorMessage(ErrnoCopy)]));
    end;
  end;