有关UDP、Mediaplayer和流的问题。敬请关注,谢谢...(100分)

  • 主题发起人 主题发起人 tongdings
  • 开始时间 开始时间
T

tongdings

Unregistered / Unconfirmed
GUEST, unregistred user!
敬请关注,

http://www.csdn.net/expert/topic/1026/1026938.xml?temp=7.842654E-02

谢谢
 
//以下是本人的实现,只能传输2K数据流,大于2k发送不成功,为什么?
//也可自己实现,贴出源代码,谢先...

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ComCtrls, ExtCtrls, NMUDP;

type
TForm1 = class(TForm)
Memo1: TMemo;
Splitter1: TSplitter;
Splitter2: TSplitter;
Memo2: TMemo;
StatusBar1: TStatusBar;
Btn_Send: TButton;
Button2: TButton;
NMUDP1: TNMUDP;
OpenDialog1: TOpenDialog;
procedure Button2Click(Sender: TObject);
procedure NMUDP1StreamInvalid(var handled: Boolean;
Stream: TStream);
procedure NMUDP1InvalidHost(var handled: Boolean);
procedure NMUDP1Status(Sender: TComponent;
status: String);
procedure Btn_SendClick(Sender: TObject);
procedure NMUDP1DataSend(Sender: TObject);
procedure NMUDP1DataReceived(Sender: TComponent;
NumberBytes: Integer;
FromIP: String;
Port: Integer);
procedure Memo1KeyPress(Sender: TObject;
var Key: Char);
private
{ Private declarations }
public
{ Public declarations }
end;


var
Form1: TForm1;

implementation

const
bufsize = 1024 * 2;
//2048, 3072, 4096

{$R *.DFM}

procedure TForm1.Button2Click(Sender: TObject);
begin

Close;
end;


procedure TForm1.NMUDP1StreamInvalid(var handled: Boolean;
Stream: TStream);
begin

StatusBar1.Panels[0].Text := 'Invalid Stream: Stream contains no data';
end;


procedure TForm1.NMUDP1InvalidHost(var handled: Boolean);
var
S: String;
begin

S := NMUDP1.RemoteHost;
if InputQuery('Invalid host', 'Specify valid hostname: ', S) then

begin

NMUDP1.RemoteHost := S;
handled := TRUE;
end;

end;


procedure TForm1.NMUDP1Status(Sender: TComponent;
status: String);
begin

StatusBar1.Panels[1].Text := status;
end;


procedure TForm1.Btn_SendClick(Sender: TObject);
var
i,count: Integer;
s: string;
SendStream: TMemoryStream;
MyStream: TMemoryStream;
leftsize,sendsize: Longint;
//buf: array[0..bufsize-1] of char;
begin

SendStream := TMemoryStream.Create;
MyStream := TMemoryStream.Create;

Memo1.SetFocus;

try
if OpenDialog1.Execute then

Memo1.Lines.LoadFromFile(OpenDialog1.FileName);

s:= Memo1.Lines.text;
if s = '' then

begin

MessageDlg('Invalid message! Please Add it...',mtError,[mbOK],0);
exit;
end;


NMUDP1.RemoteHost := '127.0.0.1';
NMUDP1.ReportLevel := Status_Basic;
NMUDP1.RemotePort := 6668;
Nmudp1.LocalPort := 6668;

MyStream.LoadFromFile(OpenDialog1.FileName);
Mystream.Position := 0;
leftsize := Mystream.Size;
//leftsize := length(s);

if leftsize > bufsize then

begin

count := leftsize div bufsize;
//´ò°ü³Éÿ°ü2048Bytes ʱµÄ´ò°ü´ÎÊý
for i := 1 to countdo

begin

//sendsize := bufsize;
sendstream.Write(s[1],bufsize);
NMUDP1.SendStream(sendstream);
leftsize := Mystream.Seek((bufsize * i), soFrombegin
ning);
if leftsize = 0 then

break;
end;

//end of [for i := 1 to countdo
]
end
else

begin

sendsize := leftsize;
SendStream.Write(s[1],sendsize);
NMUDP1.SendStream(sendstream);
end;


finally
Sendstream.Free;
Mystream.Free;
end;


end;


procedure TForm1.NMUDP1DataSend(Sender: TObject);
begin

StatusBar1.Panels[2].Text := 'Data From Memo1 to Memo2 Sent...';
end;


procedure TForm1.NMUDP1DataReceived(Sender: TComponent;
NumberBytes: Integer;
FromIP: String;
Port: Integer);
var
recStream,resultstream: TMemoryStream;
buf: array[0..2048] of char;
begin

recStream := TMemoryStream.Create;
resultstream := TMemoryStream.Create;
try
NMUDP1.ReadStream(recStream);
recstream.Position := 0;
//ÖÃÇ°
recstream.ReadBuffer(buf,NumberBytes);
//read data from recstream to buf;
if NumberBytes > bufsize then

begin

resultstream.WriteBuffer(buf,bufsize);
//resultstream.Position := 0;
Memo2.Lines.LoadFromStream(resultstream);
Statusbar1.Panels[3].Text := 'Data received '+IntToStr(NumberBytes)+' bytes from '
+FromIP+' on port '+IntToStr(Port);
numberbytes := numberbytes - bufsize;
end
else
//NumberBytes <= bufsize
begin

resultstream.WriteBuffer(buf,numberbytes);
resultstream.Position := 0;
Memo2.Lines.LoadFromStream(resultstream);
Statusbar1.Panels[3].Text := 'Data received '+IntToStr(NumberBytes)+' bytes from '
+FromIP+' on port '+IntToStr(Port);
end;

finally
recStream.Free;
end;

end;


procedure TForm1.Memo1KeyPress(Sender: TObject;
var Key: Char);
begin

if key = #13 then

self.Btn_SendClick(self);
end;


end.


//end of program
 
以上为TNMUDP传送文本流例子。只能传送2K(UDP的约束)
why?
 
下面是实现基于UDP包数据流发送源码。还存在一个问题就是大于2K包会存在一部分数据丢失现象,2K之内要点击两次才能发送成功,不知为什么。跟踪了N次。恳求解答,谢谢!
可通过E-Mail: high2point@telekbird.com.cn
或者QQ: 6376875
联系.
期待...
********************************************************************

unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
NMUDP, StdCtrls, Buttons, ExtCtrls, ComCtrls;
type
TForm1 = class(TForm)
Memo1: TMemo;
Memo2: TMemo;
StatusBar1: TStatusBar;
Splitter1: TSplitter;
SendBtn: TBitBtn;
NMUDP1: TNMUDP;
OpenDialog1: TOpenDialog;
procedure NMUDP1StreamInvalid(var handled: Boolean;
Stream: TStream);
procedure NMUDP1InvalidHost(var handled: Boolean);
procedure NMUDP1Status(Sender: TComponent;
status: String);
procedure SendBtnClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
implementation
const bufsize = 1024 * 2;
{$R *.DFM}
procedure TForm1.NMUDP1StreamInvalid(var handled: Boolean;
Stream: TStream);
begin

showmessage('Invalid Stream: Stream contains no data');
end;

procedure TForm1.NMUDP1InvalidHost(var handled: Boolean);
var
S: String;
begin

S := NMUDP1.RemoteHost;
if InputQuery('Invalid host', 'Specify valid hostname: ', S) then

begin

NMUDP1.RemoteHost := S;
handled := TRUE;
end;

end;

procedure TForm1.NMUDP1Status(Sender: TComponent;
status: String);
begin

statusbar1.SimpleText := 'Status: ' + status;
end;

//***********************************************************************************
//******* this procedure include 'send' amd ' receive' two actions with UDP ******
//*** Const type: ******************************************************************
//*** bufsize = 2 * 1024 *********************************************************
//*** variant type: *****************************************************************
//*** My: Source Stream(Memo1's text) ***************************************
//*** Send: the stream being to sent *****************************************
//*** temp: the temporary stream being to received ****************************
//*** i: circulation Integer variant **************************************
//*** leftsize: the total left size being to sent *********************************
//*** buf: buffer variant(2048 bytes) ****************************************
//***********************************************************************************
procedure TForm1.SendBtnClick(Sender: TObject);
var
My,send: TMemoryStream;
tmp: TmemoryStream;
i: Integer;
//count: Integer;
leftsize: Integer;
buf: array[0..bufsize] of char;
begin

My := TMemorystream.Create;
Send := TMemorystream.Create;
tmp := TMemorystream.Create;
if Opendialog1.Execute then

My.LoadFromFile(Opendialog1.FileName);
Memo1.Lines.LoadFromStream(My);
//send.
SetSize(bufsize);
//tmp.SetSize(bufsize);
leftsize := my.Size;
//count := leftsize div bufsize;
my.Position := 0;
i:=0;
try
While (leftsize > bufsize)do

begin

leftsize := leftsize - bufsize ;
//showmessage('My.position: ' + Inttostr(my.Position));
//......
send.
CopyFrom(my,bufsize);
my.Seek(0,sofromcurrent);
// .Position := bufsize * i;
//showmessage('My.position: ' + Inttostr(my.Position));
//......
//my.Position := bufsize * (i+1);
send.
Position := bufsize * i;
NMUDP1.SendStream(send);
NMUDP1.ReadStream(tmp);
send.
Clear;
tmp.Read(buf,bufsize);
Memo2.Lines.Add(buf);
// .LoadFromStream(tmp);
//showmessage(Memo2.Lines.Text);
//.......
tmp.Clear;
INC(i);
end;

//showmessage('My.position: ' + Inttostr(my.Position));
//.......
if (leftsize > 0) and (leftsize <= bufsize)then

begin

send.
SetSize(leftsize);
//showmessage('My.position: ' + Inttostr(my.Position));
send.
CopyFrom(my,leftsize);
//showmessage('send.
position: ' + Inttostr(send.
Position));
//......
//showmessage('My.position: ' + Inttostr(my.Position));
//......
send.
Position := 0;
NMUDP1.SendStream(send);
NMUDP1.ReadStream(tmp);
send.
Clear;
tmp.Read(buf,bufsize);
Memo2.Lines.Add(buf);
// .LoadFromStream(tmp);
tmp.Clear;
end;

Finally
tmp.Free;
send.
Free;
my.Free;
end;

StatusBar1.Panels[0].Text := 'Source bytes: ' + Inttostr(length(Memo1.Lines.Text)) +
' bytes;
Total received bytes: ' + IntTostr(length(Memo2.Lines.Text)) + ' bytes.';
end;

procedure TForm1.FormCreate(Sender: TObject);
begin

Memo1.Clear;
Memo2.Clear;
NMUDP1.RemoteHost := 'LOCALHOST';
NMUDP1.ReportLevel := STATUS_BASIC;
NMUDP1.RemotePort := 5667;
NMUDP1.LocalPort := 5667;
end;

end.


********************************************************************
 
问题出在这里,下面是你的代码:

if leftsize > bufsize then

begin

count := leftsize div bufsize;
//&amp;acute;ò°ü&amp;sup3;&amp;Eacute;&amp;Atilde;&amp;iquest;°ü2048Bytes &amp;Ecirc;±&amp;micro;&amp;Auml;&amp;acute;ò°ü&amp;acute;&amp;Icirc;&amp;Ecirc;&amp;yacute;
for i := 1 to countdo

begin

//sendsize := bufsize;
sendstream.Write(s[1],bufsize);
NMUDP1.SendStream(sendstream);
leftsize := Mystream.Seek((bufsize * i), soFrombegin
ning);
if leftsize = 0 then

break;
end;

//end of [for i := 1 to countdo
]
end
else

begin

sendsize := leftsize;
SendStream.Write(s[1],sendsize);
NMUDP1.SendStream(sendstream);
end;

收到Mail了吗?
 
to stone08

还是没有解决,不过又进了一步了.
已解决了 > 2K的循环问题,但是发现还不能全部接受到.
跟踪了N次,0~2K之间传送出现问题.
恳求帮忙.我已给你Mail了.
 
谁有做过用TMediaPlayer播放局域网上的流式文件(.mpg,.mpeg或者.asf)?
期待...
 
接受答案了.
 

Similar threads

后退
顶部