急求解决...ClientSocket通信问题? ( 积分: 50 )

  • 主题发起人 主题发起人 nhivy
  • 开始时间 开始时间
N

nhivy

Unregistered / Unconfirmed
GUEST, unregistred user!
大家好:
我用D7编了一个通信程序。使用ClientSocket控件。在跟服务器通信方面已OK。
并能通过clientsocket1.Socket.SendText(Edit1.text+#13);向服务器发送命令。
我用Memo1.Lines.Add(socket.ReceiveText);接收并显示,问题就在这里。显示结果与现实有出入。
例如Edit1发送 ALLIP:ACL=A1;
在接收服务器返回结果却变成
ALLIP:ACL=A
1;

ALLIP:
ACL=A1;
将本来一行的字符断开成两行。

命令为:EXEDP:EMG=SSD0,EM=ALL;
接收结果:
<
EXEDP:E
MG=SSD0,EM=ALL;
EMGEM SOFTWARE UNIT AND EQUIPMENT DATA

EMG
SSD0

EM SUNAME SUID
EQM

0 TEETR 2/CAA 117 067/1 C R1A01
EMGFDR 1400/CAA 117 054/1I R2A01
REPER 1000/CAA 117 2501/1K R1A01
TSR 1DKA/CAA 117 1209/M57R R3A05 TS-0
CD1R 1D12/CAA 117 1062/M57J R2A01 CD-0
JTR 1D11/CAA 117 1036/M57A R3A01 JT-0&amp;&amp;-31

KR2R 1EAK/CAA 117 1154/MK1D R3A02 KR2-0&amp;&amp;-7
LI33R 1340/CAA 117 1171/MK1A R2A07 LI3-0&amp;&amp;-127
SSTONER 1EAA/CAA 117 1141/MK1C R3A07 SSTONE-288
SLCT2R 1313/CAA 117 1160/MK1C R2A04 SLCT-0
1 TEETR 2/CAA 117 067/1 C R1A01
EMGFDR
1400/CAA 117 054/1I R2A01
REPER 1000/CAA 117 2501/1K R1A01
TSR 1DKA/CAA 117 1209/M57R R3A05 TS-1
CD1R 1D12/CAA 117 1062/M57J R2A01 CD-1
JTR 1D11/CAA 117 1036/M57A R3A01 JT-32&amp;&amp;-63
KR2R 1EAK/CAA 117 1154/MK1D R3A02 KR2-8&amp;&amp;-15
LI33R 1340/CAA 117 1171/MK1A R2A07 LI3-128&amp;
&amp;-255
SSTONER 1EAA/CAA 117 1141/MK1C R3A07 SSTONE-289
SLCT2R 1313/CAA 117 1160/MK1C R2A04 SLCT-1
2 TEETR 2/CAA 117 067/1 C R1A01
EMGFDR 1400/CAA 117 054/1I R2A01
REPER 1000/CAA 117 2501/1K R1A01
TSR 1DKA/CAA 117 1209/M57R R3A05 TS-2
CD1R 1D12/CAA
117 1062/M57J R2A01 CD-2
JTR 1D11/CAA 117 1036/M57A R3A01 JT-64&amp;&amp;-95
KR2R 1EAK/CAA 117 1154/MK1D R3A02 KR2-16&amp;&amp;-23
LI33R 1340/CAA 117 1171/MK1A R2A07 LI3-256&amp;&amp;-383
SSTONER 1EAA/CAA 117 1141/MK1C R3A07 SSTONE-290
SLCT2R 1313/CAA 117 1160/MK1
C R2A04 SLCT-2
END

<

正常显示为:
<
EXEDP:EMG=SSD0,EM=ALL;
EMGEM SOFTWARE UNIT AND EQUIPMENT DATA

EMG
SSD0

EM SUNAME SUID
EQM

0 TEETR 2/CAA 117 067/1 C R1A01
EMGFDR 1400/CAA 117 054/1I R2A01
REPER 1000/CAA 117 2501/1K R1A01
TSR 1DKA/CAA 117 1209/M57R R3A05 TS-0
CD1R 1D12/CAA 117 1062/M57J R2A01 CD-0
JTR 1D11/CAA 117 1036/M57A R3A01 JT-0&amp;&amp;-31
KR2R 1EAK/CAA 117 1154/MK1D R3A02 KR2-0&amp;&amp;-7
LI33R 1340/CAA 117 1171/MK1A R2A07 LI3-0&amp;&amp;-127
SSTONER 1EAA/CAA 117 1141/MK1C R3A07 SSTONE-288
SLCT2R 1313/CAA 117 1160/MK1C R2A04 SLCT-0
1 TEETR 2/CAA 117 067/1 C R1A01
EMGFDR 1400/CAA 117 054/1I R2A01
REPER 1000/CAA 117 2501/1K R1A01
TSR 1DKA/CAA 117 1209/M57R R3A05 TS-1
CD1R 1D12/CAA 117 1062/M57J R2A01 CD-1
JTR 1D11/CAA 117 1036/M57A R3A01 JT-32&amp;&amp;-63
KR2R 1EAK/CAA 117 1154/MK1D R3A02 KR2-8&amp;&amp;-15
LI33R 1340/CAA 117 1171/MK1A R2A07 LI3-128&amp;&amp;-255
SSTONER 1EAA/CAA 117 1141/MK1C R3A07 SSTONE-289
SLCT2R 1313/CAA 117 1160/MK1C R2A04 SLCT-1
2 TEETR 2/CAA 117 067/1 C R1A01
EMGFDR 1400/CAA 117 054/1I R2A01
REPER 1000/CAA 117 2501/1K R1A01
TSR 1DKA/CAA 117 1209/M57R R3A05 TS-2
CD1R 1D12/CAA117 1062/M57J R2A01 CD-2
JTR 1D11/CAA 117 1036/M57A R3A01 JT-64&amp;&amp;-95
KR2R 1EAK/CAA 117 1154/MK1D R3A02 KR2-16&amp;&amp;-23
LI33R 1340/CAA 117 1171/MK1A R2A07 LI3-256&amp;&amp;-383
SSTONER 1EAA/CAA 117 1141/MK1C R3A07 SSTONE-290
SLCT2R 1313/CAA 117 1160/MK1C R2A04 SLCT-2
END

<

数据显示很整齐的。请问有没有人见过这中情况?而且一行变两行显示的位置不定。

代码如下:
procedure TForm1.ClientSocket1Read(Sender: TObject;
Socket: TCustomWinSocket);

begin
Memo1.Lines.Add(socket.ReceiveText);
end;

procedure TForm1.connectClick(Sender: TObject);
begin
ClientSocket1.Active:=True;
end;

procedure TForm1.ClientSocket1Error(Sender: TObject;
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
begin
MessageDlg('服务器连接发生错误,请检查网络情况!',mtError,[mbok],0);
end;

procedure TForm1.Edit2KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if Key=VK_return then
clientsocket1.Socket.SendText(edit1.text+#13);
end;
 
大家好:
我用D7编了一个通信程序。使用ClientSocket控件。在跟服务器通信方面已OK。
并能通过clientsocket1.Socket.SendText(Edit1.text+#13);向服务器发送命令。
我用Memo1.Lines.Add(socket.ReceiveText);接收并显示,问题就在这里。显示结果与现实有出入。
例如Edit1发送 ALLIP:ACL=A1;
在接收服务器返回结果却变成
ALLIP:ACL=A
1;

ALLIP:
ACL=A1;
将本来一行的字符断开成两行。

命令为:EXEDP:EMG=SSD0,EM=ALL;
接收结果:
<
EXEDP:E
MG=SSD0,EM=ALL;
EMGEM SOFTWARE UNIT AND EQUIPMENT DATA

EMG
SSD0

EM SUNAME SUID
EQM

0 TEETR 2/CAA 117 067/1 C R1A01
EMGFDR 1400/CAA 117 054/1I R2A01
REPER 1000/CAA 117 2501/1K R1A01
TSR 1DKA/CAA 117 1209/M57R R3A05 TS-0
CD1R 1D12/CAA 117 1062/M57J R2A01 CD-0
JTR 1D11/CAA 117 1036/M57A R3A01 JT-0&amp;&amp;-31

KR2R 1EAK/CAA 117 1154/MK1D R3A02 KR2-0&amp;&amp;-7
LI33R 1340/CAA 117 1171/MK1A R2A07 LI3-0&amp;&amp;-127
SSTONER 1EAA/CAA 117 1141/MK1C R3A07 SSTONE-288
SLCT2R 1313/CAA 117 1160/MK1C R2A04 SLCT-0
1 TEETR 2/CAA 117 067/1 C R1A01
EMGFDR
1400/CAA 117 054/1I R2A01
REPER 1000/CAA 117 2501/1K R1A01
TSR 1DKA/CAA 117 1209/M57R R3A05 TS-1
CD1R 1D12/CAA 117 1062/M57J R2A01 CD-1
JTR 1D11/CAA 117 1036/M57A R3A01 JT-32&amp;&amp;-63
KR2R 1EAK/CAA 117 1154/MK1D R3A02 KR2-8&amp;&amp;-15
LI33R 1340/CAA 117 1171/MK1A R2A07 LI3-128&amp;
&amp;-255
SSTONER 1EAA/CAA 117 1141/MK1C R3A07 SSTONE-289
SLCT2R 1313/CAA 117 1160/MK1C R2A04 SLCT-1
2 TEETR 2/CAA 117 067/1 C R1A01
EMGFDR 1400/CAA 117 054/1I R2A01
REPER 1000/CAA 117 2501/1K R1A01
TSR 1DKA/CAA 117 1209/M57R R3A05 TS-2
CD1R 1D12/CAA
117 1062/M57J R2A01 CD-2
JTR 1D11/CAA 117 1036/M57A R3A01 JT-64&amp;&amp;-95
KR2R 1EAK/CAA 117 1154/MK1D R3A02 KR2-16&amp;&amp;-23
LI33R 1340/CAA 117 1171/MK1A R2A07 LI3-256&amp;&amp;-383
SSTONER 1EAA/CAA 117 1141/MK1C R3A07 SSTONE-290
SLCT2R 1313/CAA 117 1160/MK1
C R2A04 SLCT-2
END

<

正常显示为:
<
EXEDP:EMG=SSD0,EM=ALL;
EMGEM SOFTWARE UNIT AND EQUIPMENT DATA

EMG
SSD0

EM SUNAME SUID
EQM

0 TEETR 2/CAA 117 067/1 C R1A01
EMGFDR 1400/CAA 117 054/1I R2A01
REPER 1000/CAA 117 2501/1K R1A01
TSR 1DKA/CAA 117 1209/M57R R3A05 TS-0
CD1R 1D12/CAA 117 1062/M57J R2A01 CD-0
JTR 1D11/CAA 117 1036/M57A R3A01 JT-0&amp;&amp;-31
KR2R 1EAK/CAA 117 1154/MK1D R3A02 KR2-0&amp;&amp;-7
LI33R 1340/CAA 117 1171/MK1A R2A07 LI3-0&amp;&amp;-127
SSTONER 1EAA/CAA 117 1141/MK1C R3A07 SSTONE-288
SLCT2R 1313/CAA 117 1160/MK1C R2A04 SLCT-0
1 TEETR 2/CAA 117 067/1 C R1A01
EMGFDR 1400/CAA 117 054/1I R2A01
REPER 1000/CAA 117 2501/1K R1A01
TSR 1DKA/CAA 117 1209/M57R R3A05 TS-1
CD1R 1D12/CAA 117 1062/M57J R2A01 CD-1
JTR 1D11/CAA 117 1036/M57A R3A01 JT-32&amp;&amp;-63
KR2R 1EAK/CAA 117 1154/MK1D R3A02 KR2-8&amp;&amp;-15
LI33R 1340/CAA 117 1171/MK1A R2A07 LI3-128&amp;&amp;-255
SSTONER 1EAA/CAA 117 1141/MK1C R3A07 SSTONE-289
SLCT2R 1313/CAA 117 1160/MK1C R2A04 SLCT-1
2 TEETR 2/CAA 117 067/1 C R1A01
EMGFDR 1400/CAA 117 054/1I R2A01
REPER 1000/CAA 117 2501/1K R1A01
TSR 1DKA/CAA 117 1209/M57R R3A05 TS-2
CD1R 1D12/CAA117 1062/M57J R2A01 CD-2
JTR 1D11/CAA 117 1036/M57A R3A01 JT-64&amp;&amp;-95
KR2R 1EAK/CAA 117 1154/MK1D R3A02 KR2-16&amp;&amp;-23
LI33R 1340/CAA 117 1171/MK1A R2A07 LI3-256&amp;&amp;-383
SSTONER 1EAA/CAA 117 1141/MK1C R3A07 SSTONE-290
SLCT2R 1313/CAA 117 1160/MK1C R2A04 SLCT-2
END

<

数据显示很整齐的。请问有没有人见过这中情况?而且一行变两行显示的位置不定。

代码如下:
procedure TForm1.ClientSocket1Read(Sender: TObject;
Socket: TCustomWinSocket);

begin
Memo1.Lines.Add(socket.ReceiveText);
end;

procedure TForm1.connectClick(Sender: TObject);
begin
ClientSocket1.Active:=True;
end;

procedure TForm1.ClientSocket1Error(Sender: TObject;
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
begin
MessageDlg('服务器连接发生错误,请检查网络情况!',mtError,[mbok],0);
end;

procedure TForm1.Edit2KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if Key=VK_return then
clientsocket1.Socket.SendText(edit1.text+#13);
end;
 
网络的tcp发送存在&quot;粘包&quot;现象,楼主的程序最好设定数据的起止标志,用于服务器和客户端判断命令行。
 
TCP发送的缓冲区可以设大一点。例如4096字节。另外设置自己的数据起止标志,好像解决不了被TCP恶意拆行的问题吧。可能还要找找其他问题。
 
数据起止标志应该如何设置?
缓冲区大小又是如何设置?
在ClientSocket控件中好象不能设置?
能粘段代码吗?
 
数据起止标志的意思很简单,你发送的每一段代码都要带上头标记和尾标记,没有收到尾标记前就认为这一行没有结束,继续收。先吃饭,吃饱饭给你一段代码。
 
好的,先谢过你了![:)]
 
我主要是仿照一个澳大利亚的消防产品中通讯协议的做法。
下面是它的包的格式。

Byte Order DLE STX Command Network ID Zone ID Sector ID Data
Length Data DLE ETX CRC
No Bytes 1 1 1 1 1 1 1 [0-128] 1 1 2

它用DLE+STX作为包的开始,用DLE+ETX作为包的结束,只要收到DLE和STX就认为包开始传了,一直收,收到DLE+ETX才结束,中途都认为包没有传完。当然有些细节你自己需要处理的,例如怎么去搜索关键字,来判断传输进程是否结束,我用的是很低级的POS方式,查子串,一般我的包很小,查询都比较快的,不要紧。你的我看了,内容也不多,也可以这样做。
另外,DLE/STX/ETX等的定义如下,这是有标准的,不是自己随便起的。
STX 02Hex
ETX 03Hex
ACK 06Hex
NAK 15Hex
DLE 10Hex
 
有愿代码吗?参详一下好吗?
 
const
STX=$02;
ETX=$03;
ACK=$06;
NAK=$15;
DLE=$10;

var
tranStart,tranEnd:Boolean;
sRecv:String;//收到的全部内容
iStartPosition,iEndPosition:Integer;
begin
//recvStr为你刚刚收到的内容
iStartPosition:=Pos(Chr(DLE)+Chr(STX),recvStr);
if iStartPosition>0 then
begin
tranStart:=True;
sRecv:='';//清空内容
sRecv:=Copy(recvStr,iStartPosition,Length(recvStr)-iStartPosition+1);
end;
//
iEndPosition:=Pos(Chr(DLE)+Chr(ETX),recvStr);
if iEndPosition>0 then
begin
if tranStart=True then
begin
//找到末位置,处理内容。注意,如果iEndPosition<>Length(recvStr),说明结束符后面又跟有内容了,需要做额外处理
end
else begin
//没有开始标记就到末尾标记了。抛弃文本
end;
end;
end;
大概意思是这样,你要把它传输的东西看成是不连贯的来处理,才能保证任何情况下不会出错。如果违反了你的规则,例如,没有开始标记就出现末尾标记,抛弃它。如果要求数据收发不丢失,只好做自己的握手了。
 
没有代码了。2001年做的东西。
 
是你代码的问题, socket并不会保证一次发送全部的数据,
当一行的字符串分两次发送时, 这时你用下面的语句来显示
Memo1.Lines.Add(socket.ReceiveText);
当然会分行了.

应该
S:= S + socket.ReceiveText;

在全部接收完后才
Memo1.Lines.Add(S);
 
但在接收除指令外的结果,同样出现这种情况.
 
兄弟,来看看
www.51merit.com
winsock专区中尹天篇和屠龙篇,相信你会明白道理,
我是专门做企业级应用开发的!
 
有无人再给我好的点子。我会给你好多分。
 
等待高手们的回答.
 
后退
顶部