SocketServer发送数据有限制吗? ( 积分: 100 )

  • 主题发起人 主题发起人 笑江横
  • 开始时间 开始时间

笑江横

Unregistered / Unconfirmed
GUEST, unregistred user!
我用SocketServer和SocketClient在局域网内收发信息,发现了一个问题,如果SocketServer发送的数据大于81个字节的时候,就再也接收不到SocketClient发送过来的信息,但是SocketServer发送到SocketClient的数据,SocketClient能正常接收,不知道为什么。
 
我用SocketServer和SocketClient在局域网内收发信息,发现了一个问题,如果SocketServer发送的数据大于81个字节的时候,就再也接收不到SocketClient发送过来的信息,但是SocketServer发送到SocketClient的数据,SocketClient能正常接收,不知道为什么。
 
客户端发送大于81字节的数据到服务端,服务端接收完之后,也是只能发送,不能接收了,这个问题真的很奇怪。
 
难道大家没有碰到这个问题吗
 
好失望啊,我在大富翁这么久,才提问了4个问题,居然有3个问题没有人回答,有一个自己解决了,分数又不能回收
 
原代码可以看看吗
 
好象的在SocketConnection上加上一写参数,就可以扩大了~
 
这个问题。。学习ing。。。
帮顶~!
 
Server端:
发送的代码
procedure TForm1.btnSendClick(Sender: TObject);
var
i:integer;
Count:Integer;
begin
Count:=Server.Socket.ActiveConnections;
for i:=0 to Count-1 do
Server.Socket.Connections.SendText(edtSend.text);
end;
接收的代码
procedure TForm1.ServerClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
RecStr: string; //接收到的信息,终端编号
begin
RecStr := Socket.ReceiveText;
Memo1.Text := RecStr;
end;

Client端:
发送
procedure TfrmMain.btnSendClick(Sender: TObject);
begin
if client.Active then
begin
Client.Socket.SendText(Edit1.Text);
edit1.SelectAll;
end;
end;
接收:
procedure TfrmMain.ClientRead(Sender: TObject; Socket: TCustomWinSocket);
var
Str: String;
begin
Str := Socket.Recievetext;
Memo1.Text := Str;
end;
 
循一遍,如果状态是连接的,才发咚咚
 
肯定是连接的,因为客户端能收到服务端发送的数据
 
感觉是缓冲的问题

procedure TfrmMain.ClientRead(Sender: TObject; Socket: TCustomWinSocket);
var
Str: String;
begin
Str := Socket.Recievetext;
Memo1.Text := Str;
end;

这句话,是不是因为没有接收手完毕

看看这个帖子

http://www.delphibbs.com/delphibbs/dispq.asp?LID=2179547
请教3个深入Socket的难题-----分全给了
 
我也觉得是缓冲的问题,但是不知该如何下手解决
procedure TForm1.ServerClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
p:pchar;
length:longint;
Count,i:Integer;
begin
p:=nil;
while socket.ReceiveLength>0 do begin
length:=socket.receivelength;
Getmem(p,length);
TRY
socket.ReceiveBuf(p^,socket.receivelength);
Memo1.Text := String(P);
FINALLY
FreeMem(p);
END;
end;
end;
这样也不行
 
一起,接收文本应该没有问题的,不过如果你接收的二进制文件,就不能这样了,那个ReceiveLength是准确的,我以前碰到过一次,帮助里是这么说的

Note: ReceiveLength is not guaranteed to be accurate for streaming socket connections.

也就是不保证流传输时的正确性,我记得是直接用ReceiveBuf函数去读取指定buf大小的内容,事先Server端要发送一个数字,告诉Client端将要发送的内容大小,然后Client端读取的时候就累加判断,时间隔太久了,有点记不住了,大概是这个意思,我转了一篇类似的文章,看看有参考价值没有

http://www.delphibbs.com/delphibbs/dispq.asp?LID=156184

Client端:(发方)

private
stream : TMemoryStream; //定义内存流,其实用
文件流也可以
size,count : integer; //文件大小
end;

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
begin
ClientSocket1.Address := Edit1.Text;
ClientSocket1.Active := True;
end;

procedure TForm1.ClientSocket1Connect(Sender: TObject;
Socket: TCustomWinSocket);
begin
StatusBar1.SimpleText := 'Connected to '+Socket.RemoteAddress;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
stream := TMemoryStream.Create;
if OpenDialog1.Execute then
begin
stream.LoadFromFile(OpenDialog1.FileName);
size := stream.Size; //获得文件大小
count := 0;
ClientSocket1.Socket.SendText(inttostr(size)); //先发送大小
end;
end;

procedure TForm1.ClientSocket1Read(Sender: TObject;
Socket: TCustomWinSocket);
var
rcvtxt : string;
buf : array [1..2048] of char;
left : integer;
begin
rcvtxt := Socket.ReceiveText;
left := size - count; //未读字节数
if AnsiPos('go',rcvtxt)=1 then
begin
if sizeof(buf)<left then //若满一块则读一块
begin
stream.Read(buf,sizeof(buf));
Socket.SendBuf(buf,sizeof(buf));
count := count + sizeof(buf);
end
else //不满则发剩余的
begin
stream.Read(buf,left);
Socket.SendBuf(buf,left);
end;
end;
end;


Server端(收方)


private
Tof : file;
size,count :integer;
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.CutFirst(denstr: string;scrstr: string);
var
len :integer;
begin
len := length(scrstr);
denstr := copy(scrstr,2,(len-1));
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
ServerSocket1.Active := True;
StatusBar1.SimpleText := 'Listening...';
end;

procedure TForm1.ServerSocket1Accept(Sender: TObject;
Socket: TCustomWinSocket);
begin
StatusBar1.SimpleText := 'Connected from '+ Socket.RemoteAddress;
end;

procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
buf : array [1..2048] of char;
rcvtxt : string;
left,len : integer;
begin
len := Socket.ReceiveLength;
if len<10 then //若长度小于10则认为是文件长度
begin
rcvtxt := Socket.ReceiveText;
size := strtoint(rcvtxt);
count := 0;
if SaveDialog1.Execute then
begin
AssignFile(ToF, SaveDialog1.FileName);
Rewrite(ToF, 1);
end;
Socket.SendText('go');
end
else
begin
left := size - count; //未写的字节数
if sizeof(buf)<left then //满一块则写一块
begin
Socket.ReceiveBuf(buf,sizeof(buf));
BlockWrite(Tof,buf,sizeof(buf));
count := count + sizeof(buf);
Socket.SendText('go');
end
else //否则写剩余字节数
begin
Socket.ReceiveBuf(buf,left);
BlockWrite(Tof,buf,left);
CloseFile(Tof);
end;
end;
end;


这个程序在长度的判断上通用性还不够强,但只需
稍加改动就可以实用了
 
www.51merit.com
上have
 
问题解决了
 
后退
顶部