传送端:
procedure Tf_Main.rb_upClick(Sender: TObject);
var
nID:integer;
nSize:Integer;
n:Integer;
p:pByte;
data:TmemoryStream;
begin
data:=TmemoryStream.Create;
try
data.LoadFromFile(extractfilepath(application.EXEName)+'xfd.tmp');
with ClientSocket1 do
begin
open;
nSize:=data.Size;
p:=data.Memory;
while (nSize>0) do
begin
n:=nSize;
if (n>8192) then
n:=8192;
n:=Socket.SendBuf(p^,n);
//
if (n<=0) then
Raise Exception.Create('发送文件失败!');
Inc(p,n);
Dec(nSize,n);
end;
close;
end;
except on e:Exception do
showmessage(e.Message);
end;
data.Free;
end;接收端:
procedure Tf_Server.ServerSocket1Accept(Sender: TObject;
Socket: TCustomWinSocket);
var
nID:integer;
nSize:Integer;
n:Integer;
p:pByte;
data:TmemoryStream;
begin
data:=TmemoryStream.Create;
GetMem(p,8192);
try
while (nSize>0) do
begin
n:=nSize;
if (n>8192) then
n:=8192;
n:=Socket.ReceiveBuf(P^,n);
if (n<=0) then
Raise Exception.Create('');
data.Write(p^,n);
Dec(nSize,n);
end;
data.SaveToFile(extractfilepath(application.EXEName)+'xfd.tmp');
except
end;
FreeMem(p);
data.Free;
end;每次都是提示:发送文件失败!
procedure Tf_Main.rb_upClick(Sender: TObject);
var
nID:integer;
nSize:Integer;
n:Integer;
p:pByte;
data:TmemoryStream;
begin
data:=TmemoryStream.Create;
try
data.LoadFromFile(extractfilepath(application.EXEName)+'xfd.tmp');
with ClientSocket1 do
begin
open;
nSize:=data.Size;
p:=data.Memory;
while (nSize>0) do
begin
n:=nSize;
if (n>8192) then
n:=8192;
n:=Socket.SendBuf(p^,n);
//
if (n<=0) then
Raise Exception.Create('发送文件失败!');
Inc(p,n);
Dec(nSize,n);
end;
close;
end;
except on e:Exception do
showmessage(e.Message);
end;
data.Free;
end;接收端:
procedure Tf_Server.ServerSocket1Accept(Sender: TObject;
Socket: TCustomWinSocket);
var
nID:integer;
nSize:Integer;
n:Integer;
p:pByte;
data:TmemoryStream;
begin
data:=TmemoryStream.Create;
GetMem(p,8192);
try
while (nSize>0) do
begin
n:=nSize;
if (n>8192) then
n:=8192;
n:=Socket.ReceiveBuf(P^,n);
if (n<=0) then
Raise Exception.Create('');
data.Write(p^,n);
Dec(nSize,n);
end;
data.SaveToFile(extractfilepath(application.EXEName)+'xfd.tmp');
except
end;
FreeMem(p);
data.Free;
end;每次都是提示:发送文件失败!
n:=Socket.SendBuf(p^,n);
//
if (n<=0) then
Raise Exception.Create('发送文件失败!');
Inc(p,n);你的Socket是一个什么控件呀,,是否已经正确连接到你的ServerSocket呀,传输文件这样的功能,网络中有非常多的例子了,你可以参考一下1.在CSDN中查一下历史的帖子,FAQ
2.到www.delphifans.com 有很多相关的代码的
TClientSocket的ClientType:=ctBlocking;ClientSocket能正确连接到ServerScoket如果在n:=Socket.SendBuf(p^,n);后加上showmessage(inttostr(n));需要每次点击对话框,最终是可以正常接收的我不知道问题出在哪儿,请各位大侠指点一下
好象应该改成:p: ^DWORD;
2 服务端部分就有点怪了, 放在 OnAccept 事件中去阻塞, OnAccept 有没在 TSocketClientThread 调度这个我记不得了, 改到 OnRead 中去试试看吧, 这个肯定是 TSocketClietnThread 调度执行的
var
nID:integer;
nSize:Integer;
n:Integer;
p:pByte;
data:TmemoryStream;
begin
data:=TmemoryStream.Create;
GetMem(p,8192);
try
while (nSize>0) do // 这句第一次执行时 nSize 是多少? 很想骂人了, 这个 while 根本一次就没执行就退出了, 后面发送的数据在 OnRead 事件中触发却没有任何的接收超时了
begin
n:=nSize; // 这里又是多少? 连个初值都没有
if (n>8192) then // 这里 n 有可能比 8192 大?
n:=8192;
n:=Socket.ReceiveBuf(P^,n);
if (n<=0) then
Raise Exception.Create('');
data.Write(p^,n);
Dec(nSize,n);
end;
data.SaveToFile(extractfilepath(application.EXEName)+'xfd.tmp');
except
end;
FreeMem(p);
data.Free;
end;本质问题, 新鸟.
你没法在 TCP 的 socket 下知道后面的包大小, 至少你应该在发送数据前定义一个包头, 包头里面可以包括文件名, 目期, 关键的还是个文件尺寸, 像下面
TFileHdr = packed record
HdrSize: Integer;
Name: array[0..80] of char;
Date: TDateTime;
Size: Integer;
end;发送部分加上
open; 后
FileHdr.HdrSize := sizeof(TFileHdr);
...
nSize:=data.Size;
FileHdr.Size := nSize;
Socket.SendBuf(FileHdr, SizeOf(FileHdr));
这边强调一个事实就是, socket 不像是帮助中所说发送成功的长度是任何大小, 而有个最小成功大小, 因网不同而有 576-1460-3xxx 等不同数, 换名话说, 576 字节以下的一组数据是一定会发送成功, 因此像 TCP 的包头不因大于 576 字节, 嗯, 这是一个默认的少有文档会详细说事实. 但由于另一些特别原因
1. 一般会把头 size 这个东东定义在结构的最头部, 为的是跟嵌入系统这类东东打交道时, 他们的资源很有限
2. 把头后面会更的大小定义在头的最后部分懒得说了, 服务端
直接用
while nSize > 0 do
nSize - Socket.SendBuf(p^, nSize);
那个 8192 没有一种网络能一次到达, socket 一次能发送的大小是 MTU 决定的, 宽带就是 1460, modern 是 576
nSize:=data.Size;
if (socket.SendBuf(nSize,SizeOf(nSize)) <> SizeOf(nSize)) then
Raise Exception.Create('发送文件大小错误!');
p:=data.Memory;
其实我的代码是按照delphi6高级编程中的例程输入的,我所迷惑的是:
如果在n:=Socket.SendBuf(p^,n);后加上showmessage(inttostr(n));需要每次点击对话框,最终是可以正常接收的