EDIT1:我在win7x86上尝试过它并且有效。这肯定听起来是一个x64问题......如何在Windows x64机器上发送TCP套接字“x86”样式?
EDIT2:附上* .pcap文件,而不是像@RemyLebeau那样的截图。
我有这个文本字符串要发送到打印机,它不需要换行/ CRLF /等来理解代码,这意味着,在每个单词到达另一边后它会打印出来。
打印机是RS232,但我使用研华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文件: link
完全相同的程序,x86: link
与TIdClientSocket相同的文字: (UsaNagle默认为真,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: link
完全相同的程序,x86: link
答案 0 :(得分:1)
根据.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
确认,然后断开连接。
另一方面,Win7x64系统正在执行以下操作:
发送:
^
哪个是确认的,然后发送:
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
。
如果没有看到您的实际代码,则无法进一步解决此问题。否则,您应该在代码中添加一些日志记录,以便了解它在每个步骤中实际执行的操作(例如关闭套接字的时间和原因)。