Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sockets TCP套接字发送在Windows中工作,32位,但不是64位_Sockets_Windows 7_Tcp_Windows Xp_Wireshark - Fatal编程技术网

Sockets TCP套接字发送在Windows中工作,32位,但不是64位

Sockets TCP套接字发送在Windows中工作,32位,但不是64位,sockets,windows-7,tcp,windows-xp,wireshark,Sockets,Windows 7,Tcp,Windows Xp,Wireshark,EDIT1:我在win7x86中试用过,效果很好。听起来确实是x64的问题。。。如何在windows x64计算机中发送TCP套接字“x86”样式 EDIT2:附加了*.pcap文件,而不是@RemyLebeau善意询问的截图 我将这个文本字符串发送到打印机,它不需要换行/CRLF/etc来理解代码,这意味着,在每个单词到达另一侧后,它将打印 打印机是RS232,但我正在使用Advantech ADAM4577以太网-RS232网关转换信号。我所要做的就是打开一个到网关的TCP连接并吐出字符串,

EDIT1:我在win7x86中试用过,效果很好。听起来确实是x64的问题。。。如何在windows x64计算机中发送TCP套接字“x86”样式

EDIT2:附加了*.pcap文件,而不是@RemyLebeau善意询问的截图

我将这个文本字符串发送到打印机,它不需要换行/CRLF/etc来理解代码,这意味着,在每个单词到达另一侧后,它将打印

打印机是RS232,但我正在使用Advantech ADAM4577以太网-RS232网关转换信号。我所要做的就是打开一个到网关的TCP连接并吐出字符串,这是一个:

  ^XA~TA000~JSN^LT0^MMT^MNW^MTT^PON^PMN^LH0,0^JMA^PR3,3^MD10^JUS^LRN^CI0^XZ
  ^XA^LL0168
  ^PW272
  ^FT61,34^A0N,28,28^FH\^FD2053200863^FS
  ^BY2,3,91^FT47,138^BCN,,Y,N
  ^FD>;9678130580^FS
  ^PQ1,0,1,Y^XZ
我正在使用Delphi,所以我尝试了TClientSocket:

unit Unit2;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, System.Win.ScktComp, Vcl.StdCtrls;

type
  TForm2 = class(TForm)
    Button1: TButton;
    ClientSocket1: TClientSocket;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure ClientSocket1Error(Sender: TObject; Socket: TCustomWinSocket;
      ErrorEvent: TErrorEvent; var ErrorCode: Integer);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

procedure TForm2.Button1Click(Sender: TObject);
begin
  if not ClientSocket1.Active then
  begin
    ClientSocket1.Port := 9100;
    ClientSocket1.Host := '10.6.2.140';
    ClientSocket1.Address := '10.6.2.140';
    ClientSocket1.ClientType := ctNonBlocking;
    ClientSocket1.Open;
  end;

end;

procedure TForm2.Button2Click(Sender: TObject);
var
  zcode : string;
begin
 zcode :=  '^XA~TA000~JSN^LT0^MMT^MNW^MTT^PON^PMN^LH0,0^JMA^PR3,3^MD10^JUS^LRN^CI0^XZ' +
            '^XA^LL0168' +
            '^PW272' +
            '^FT61,34^A0N,28,28^FH\^FD2053200863^FS' +
            '^BY2,3,91^FT47,138^BCN,,Y,N' +
            '^FD>;9678130580^FS' +
            '^PQ1,0,1,Y^XZ';

  ClientSocket1.Socket.SendText(zcode);
end;

procedure TForm2.ClientSocket1Error(Sender: TObject; Socket: TCustomWinSocket;
  ErrorEvent: TErrorEvent; var ErrorCode: Integer);
begin
      ShowMessage(IntToStr(ErrorCode));
      ErrorCode := 0;
end;

end.
一段时间后,我得到:

Socket Error 10053 (WSAECONNABORTED)
以下是x64计算机中已过滤的pcap文件:

完全相同的程序,x86:

与TIdClientSocket相同的文本: (UsaNagle默认为true,IpVersion为IPv4

unit Unit2;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, IdBaseComponent, IdComponent,
  IdTCPConnection, IdTCPClient, Vcl.StdCtrls;

type
  TForm2 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    IdTCPClient1: TIdTCPClient;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

procedure TForm2.Button1Click(Sender: TObject);
begin
  if not IdTCPClient1.Connected then
  begin
    IdTCPClient1.Host := '10.6.2.140';
    IdTCPClient1.Port := 9100;
    idTCPClient1.Connect;
  end;


end;

procedure TForm2.Button2Click(Sender: TObject);
var
  zcode : string;
begin
 zcode :=  '^XA~TA000~JSN^LT0^MMT^MNW^MTT^PON^PMN^LH0,0^JMA^PR3,3^MD10^JUS^LRN^CI0^XZ' +
            '^XA^LL0168' +
            '^PW272' +
            '^FT61,34^A0N,28,28^FH\^FD2053200863^FS' +
            '^BY2,3,91^FT47,138^BCN,,Y,N' +
            '^FD>;9678130580^FS' +
            '^PQ1,0,1,Y^XZ';

  IdTCPClient1.IOHandler.WriteLn(zcode);
end;

end.
pcap文件,x64:

完全相同的程序,x86:

根据.pcap文件:

WinXPx86系统正在执行以下操作:

发送:

^
^
已确认,然后发送:

XA~TA000~JSN^LT0^MMT^MNW^MTT^PON^PMN^LH0,0^JM
A^PR3,3^MD10^JUS^LRN^CI0^XZ^XA^LL0168^PW272^FT61,34^A0N,28,28^FH\^FD2053200863^FS^BY2,3,91^FT47,138^BCN,,Y,N^FD>;9678130580^FS^PQ1,0,1,Y^XZ
XA~TA000~JSN^LT0^MMT^MNW^MTT^PON^PMN^LH0,0^JMA^PR3,3^MD10^JUS^LRN^CI0^XZ^XA^LL
已确认,然后发送:

XA~TA000~JSN^LT0^MMT^MNW^MTT^PON^PMN^LH0,0^JM
A^PR3,3^MD10^JUS^LRN^CI0^XZ^XA^LL0168^PW272^FT61,34^A0N,28,28^FH\^FD2053200863^FS^BY2,3,91^FT47,138^BCN,,Y,N^FD>;9678130580^FS^PQ1,0,1,Y^XZ
XA~TA000~JSN^LT0^MMT^MNW^MTT^PON^PMN^LH0,0^JMA^PR3,3^MD10^JUS^LRN^CI0^XZ^XA^LL
确认,然后断开连接

另一方面,Win7x64系统正在执行以下操作:

发送:

^
^
已确认,然后发送:

XA~TA000~JSN^LT0^MMT^MNW^MTT^PON^PMN^LH0,0^JM
A^PR3,3^MD10^JUS^LRN^CI0^XZ^XA^LL0168^PW272^FT61,34^A0N,28,28^FH\^FD2053200863^FS^BY2,3,91^FT47,138^BCN,,Y,N^FD>;9678130580^FS^PQ1,0,1,Y^XZ
XA~TA000~JSN^LT0^MMT^MNW^MTT^PON^PMN^LH0,0^JMA^PR3,3^MD10^JUS^LRN^CI0^XZ^XA^LL
但在确认之前断开连接

^LL
部分之前,他们正在发送准确的数据。但是,此活动向我建议:

  • x86和x64代码可能使用相同的代码逻辑,也可能不使用相同的代码逻辑,因为它们使用不同的帧发送相同的TCP数据(尽管这可能只是与套接字内部使用的Nagle算法有关)

  • 在Win7x64上,套接字被过早断开,这可能是一个编码问题,例如,如果您过早关闭
    TClientSocket
    ,以响应代码遇到的错误


  • 如果看不到您的实际代码,就无法进一步解决此问题。否则,您应该在代码中添加一些日志记录,以便了解它在每个步骤中实际执行的操作(例如何时以及为什么关闭套接字).

    您的屏幕截图没有用处,无法阅读。请将截图导出到.pcap文件,以便其他人可以实际打开并查看。@RemyLebeau按照您的要求进行了编辑。提前感谢!下次,请自己预筛选.pcap文件。您不必导出所有捕获的内容,您可以导出过滤后的数据。Indy的
    writeeLn()
    在文本之后发送CRLF。TClientSocket的
    SendText()
    不会。请使用Indy的
    Write()
    来匹配TClientSocket的行为。谢谢,尝试了Write(),结果相同。打印机本身并不关心额外的CRLF:)Remy,谢谢您的洞察力!但是,这些转储不是来自Delphi程序,而是来自Hyperterminal的“发送文本文件”。如果Hyperterminal在x64下出现问题,那么它可能只是一个有缺陷的x64实现。您说过您的Delphi代码中有类似的问题,您可以控制它,所以请显示该代码。您说您正在使用
    TClientSocket
    ,您对其他套接字库(如Indy、ICS或Synapse)有相同的问题吗?我发现很难相信WinSock本身会如此糟糕。到目前为止,我非常感谢您的帮助。我从来没有想过它会是一个有马车的超级终端,哦,好吧!我已经附加了ClientSocket和IdTCPClient的新文件和代码。如您所见,它们在x86中工作,而在x64中的工作方式完全不同。我还尝试在IdTCPClient上将UseNagle设置为false,但没有更改。查看最新的.pcap文件,我发现它们之间唯一的真正区别是x64 TCP头比x86 TCP头大12字节。x64正在指定x86未指定的其他TCP选项。可能您的RS232网关设备没有正确处理这些额外字节。我建议您设置一个单独的echo服务器,并将x86和x64客户端连接到它。确保它能够正确接收客户端请求。如果是这样,那么您的问题肯定与RS232网关设备的问题有关。有没有办法强制我的系统使用与x86机器相同大小的头文件?我怎样才能使这个“向后兼容”?问题肯定是网关,但是如果我不能直接切换硬件呢?