【发布时间】:2013-09-11 03:16:53
【问题描述】:
EDIT1:我已经在 win7x86 中尝试过它并且它有效。听起来肯定是 x64 问题...如何在 windows x64 机器上发送 TCP 套接字“x86”样式?
EDIT2:按照@RemyLebeau 的要求,附上了 *.pcap 文件而不是屏幕截图。
我有这个要发送到打印机的文本字符串,它不需要换行/CRLF/等来理解代码,这意味着,在每个单词到达另一端后它就会打印出来。
打印机是 RS232,但我使用 Advantech ADAM4577 Ethernet-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 默认为 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: link
完全相同的程序,x86: link
【问题讨论】:
-
你的截图没用,无法阅读。将捕获导出为 .pcap 文件,以便其他人可以实际打开并查看它们。
-
@RemyLebeau 按您的要求编辑。提前致谢!
-
下次自己预过滤 .pcap 文件。您不必导出捕获的所有内容,您可以导出过滤后的数据。
-
Indy 的
WriteLn()在文本之后发送一个 CRLF。 TClientSocket 的SendText()没有。改用 Indy 的Write()来匹配 TClientSocket 的行为。 -
谢谢,尝试使用 Write(),结果相同。无论如何,打印机本身并不关心额外的 CRLF :)
标签: sockets windows-7 tcp windows-xp wireshark