怎样用TCP协议传输多媒体文件,比如mp3,或者.RM文件?(48分)

  • 主题发起人 主题发起人 紫金山
  • 开始时间 开始时间

紫金山

Unregistered / Unconfirmed
GUEST, unregistred user!
winAPI或者Tclientsocket和Tserversocket都可以,是从服务器传到客户端的.
 
传输多媒体文件和普通文件有什么区别吗?[?]
传输单个文件的方法
原理说明:发送方首先发送文件大小,接收方创建一个Stream,准备接收,发送准备好信息,
发送方发送整个流,如果流比较大,系统会自动分包发送,所以在客户端要做一个拼接处
理。即判断接收后的Stream的大小,如果小于文件大小,则继续接收,否则接收完成。
//********************************************************
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;
注:代码是转贴别人的。
 
太长。
用TNMStrmServ和TNMStrm最好,传mp3,或者.RM文件没问题。
 
laqo:我用到的是服务器端为有实际IP的机器,而客户端是某一局域网里的机子.而且又是服务器
传输文件给客户机,所以用TNMStrmServ和TNMStrm可能不行(无法建立连接)
youngsun:你说的程序你运行过么?效果怎样,反正我用的类似方法,结果无法传输.mp3和.rm
文件,报错I/O error103.所以求救!
 
我传过文件,但没有试过rm和mp3类型的文件,我试一下。
 
RM和MP3都可以说是2进制数据文件,文本文件是2进制文件,只是认为划分为什么类型的
文件。
 
什么意思?
 
我查到I/O ERROR103原因是文件没有打开,但是文本文件却没有这种情况出现,这是为什么?
为什么不能传输。RM文件呢
我用到的语句:BlockRead(Ftrans,BlockBuf,Blocklen)
其中BlockBuf:Array [0..Blocklen-1]of byte;
Ftrans是一个。RM文件
 
我弄错了,原来出现错误的原因不是类型,而是大小。文件一大就会产生I/O error103的错误
这是为什么?那位仁兄告诉小弟,或者该怎么解决这个问题?
 

应该不会吧?初学Delphi时用BlockRead,BlockWrite写一个文件分割器时,
分割300多M的文件都没问题。

试试这样:
文件类型为:file of byte;
type
buf = Array [0..Blocklen-1]of byte;

BlockBuf: ^buf;

BlockRead(Ftrans,BlockBuf^,Blocklen,iReadLen);//最后一个参数是实际读取的长度


 
影 子:在下正是用的你的那种格式啊?!!!
 
BlockRead(Ftrans,BlockBuf[0],Blocklen,iReadLen);//效果应该一样的啊
 
影 子先生(女士)还看出有什么不对?
望各位指教!!
YoungSun:你程序运行的怎样?
 
用TNMStrmServ和TNMStrm可能不行(无法建立连接)?
ClientSocket能连接的地方TNMStrm就行.
多大的文件都没问题.

 

我原以为是接收端出错。
也许,是发送比Blocklen小的文本文件不会出错,而比Blocklen大的文件会出错。
如果是这样,是读文件的语句没有控制好。
 
你把原文件的只读属性去掉!
 
我已经知道自己错在那里了!多谢各位!送分
 
后退
顶部