关于socket发送长字符串的问题(50分)

  • 主题发起人 主题发起人 0.5
  • 开始时间 开始时间
0

0.5

Unregistered / Unconfirmed
GUEST, unregistred user!
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ScktComp, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
ClientSocket: TClientSocket;
procedure Button1Click(Sender: TObject);
procedure ClientSocketRead(Sender: TObject; Socket: TCustomWinSocket);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
TestStr: String;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
len:word;
buf:array of char;
msg:string;
begin
Try
ClientSocket.Active := true;
Except
MessageBox(0,'连接失败,请查看服务端是否有启动!','',MB_OK + MB_ICONWARNING);
end;
Msg := TestStr;
Len := Length(Msg);
SetLength(buf,Len);
Move(Msg[1],buf[0],Len);
self.ClientSocket.Socket.SendBuf(buf[0],Len);
end;

procedure TForm1.ClientSocketRead(Sender: TObject;
Socket: TCustomWinSocket);
var
len:word;
buf:array of char;
msg:string;
begin
try
len := Socket.ReceiveLength;
setlength(buf, len);
Socket.ReceiveBuf(buf[0], len);
setlength(msg, len);
Move(buf[0], msg[1], len);
self.Memo1.Lines.Add(msg);
except
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
TestStr := 'BBBB110270469 8574677 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxEEEE';
end;

end.

以上是我的代码,现在可以正常发送,但是如果服务器端返回的字符串长度过长,则客户端不能完全收到,请问怎么解决?谢谢
 
好象没办法解决,以前提过同样的问题,一直没人给予回答。
我是用来发邮件,后来邮件改为发送附件文本了。
 
用Stream进行发送接受
为了更快还可以在发送时对流进行压缩,接收时解压,别说是长文本,就是图片或文件也可以.
 
最好能给个例子,我不接收大文件,只是一个很长的字符串
 
发送组件,流有一个方法的啊,
可以当作一个属性,试试,
 
To Clearboy
能说得详细点儿吗?
 
可以写个拼字串的方法 把想发的分成多个小段 然后再发 接受端也是收到消息后拼好后再处理
 
ClientSocket和ServerSocket每次发送的内容不要超过4K字节
 
定义好一个格式,把内容读到流中 分包发送, 客户端接收到数据读到一个流里 如果是最后一个包 把流显示出来
 
我觉得好像不是长度太大的问题,看网卡支持多少,一个包最多可以达到8k,况且如果长度超长,socket也会自动分包发送的。似乎你的这个问题出在字符串里面包含了换行符,比如#13,你看看,如果对了别忘了给分
 
自定义一个结束标志,服务器发送完加结束标记
客户端用while循环读字符直到标志位结束
 
TO 贴主我成经和你遇到相同问题:用socket的sendtext发送字符串的时候当数据量太大就接收不到或不完整(你用的SendBuf)我想也差不多。出现这个问题最主要的问题就是,发和收两端的数据接收不同步。你可以采用我楼上ansean师兄的办法,也可以在你SendBuf之前测试出数据量的大小并通知接收端。当接收端在收到数据后就与发送端发过来的数据量大小做比较如果没有接收完在继续接收,以此来保证接收到数据的完整性。
 
用setsockopt()设置socket缓冲区的大小
 
如果我这样写函数还能执行ClientSocketRead事件中的代码吗?
Function(msg: String):boolean;
begin
ClientSocketRead.Socket.SendText(msg);
if ClientSocketRead.Socket.ReceiveText = '0000' then
result := true;
end;
 
if FClientSocket.CanRead(5000) then
if FClientSocket.CanRcvNum > 0 then
begin
FillChar(Buffer, SizeOf(Buffer), 0);
FClientSocket.Recive(Buffer, SizeOf(Buffer));
if Assigned(FClientSocket.ReadProc) then
TReadProc(FClientSocket.ReadProc)(FClientSocket, Buffer);
end
else
Break;
 
procedure TForm1.ClientSocketRead(Sender: TObject;
Socket: TCustomWinSocket);
var
len:word;
buf:array of char;
msg:string;
begin
try
len := Socket.ReceiveLength;
while len > 0 do begin
setlength(buf, len);
Socket.ReceiveBuf(buf[0], len);
setlength(msg, len);
Move(buf[0], msg[1], len);
self.Memo1.Lines.Add(msg);
len:= Socket.ReceiveLength;
end;
except
end;
end;
 
发送长的字符串就要进行相应的等待,等receivelength=0时才能说明都接收完了
 
多谢各位,这个问题已经解决了。
 
后退
顶部