犹豫再三,我还是决定,把这个帖子发在VC的版块当中,希望各位大侠帮助。以下这个Delphi程序是目前已经达成我需要的功能的程序,也就是从不断接收服务器发送的YUV视频数据,然后显示出来。我看了一下procedure TCPSockReceive(aSocket: TLSocket);这个函数,这个函数当中,直接使用
res := aSocket.Get( buffer[0], sizeof(buffer) );来获取从socket中的数据(应该没有错吧,我对Delphi并不了解)。问题就这样产生了,为什么与服务器建立了连接之后,使用recv()函数,却始终读不到数据呢?要说我的VC程序,那就一个简单就可以概括。 源代码就贴在Delphi代码的后面吧。之前一直没有贴过代码,现在使用添加源码的功能,希望不要出什么错误,方便大侠查看代码。unit main;{$mode objfpc}{$H+}interfaceuses
Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
ExtCtrls, StdCtrls, ComCtrls, lNetComponents, lNet, Spin, Math,
IniPropStorage;type { TMainForm } TMainForm = class(TForm)
Connect: TButton;
IniPropStorage1: TIniPropStorage;
StatusBar: TStatusBar;
Stop: TButton;
Host: TEdit;
Video: TGroupBox;
VideoFrame: TImage;
TCPSock: TLTCPComponent;
Port: TSpinEdit; procedure ConnectClick(Sender: TObject);
procedure StopClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure TCPSockConnect(aSocket: TLSocket);
procedure TCPSockError(const msg: string; aSocket: TLSocket);
procedure TCPSockReceive(aSocket: TLSocket);
procedure DisplayFrame(stream: TStream);
private public
Stream1: TMemoryStream;
end; var
MainForm: TMainForm;
TmpImage : TJPEGImage;
BmpImage : TBitmap;implementation{ TMainForm }function ByteToHex(InByte:byte):shortstring;
const Digits:array[0..15] of char='0123456789ABCDEF';
begin
result:=digits[InByte shr 4]+digits[InByte and $0F];
end;procedure TMainForm.ConnectClick(Sender: TObject);
begin
Stream1.SetSize(0);
StatusBar.SimpleText := 'connecting...';
TCPSock.Connect(Host.Text, Port.Value);
end;procedure TMainForm.StopClick(Sender: TObject);
begin
TCPSock.Disconnect;
StatusBar.SimpleText := 'stopped';
end;procedure TMainForm.FormCreate(Sender: TObject);
begin
Stream1 := TMemoryStream.Create;
TmpImage := TJPEGImage.Create;
BmpImage := TBitmap.Create;
Video.DoubleBuffered:=True; IniPropStorage1.Restore;
MainForm.Width := StrToInt(IniPropStorage1.StoredValue['width']);
MainForm.Height := StrToInt(IniPropStorage1.StoredValue['height']);
MainForm.Host.Text := IniPropStorage1.StoredValue['host'];
MainForm.Port.Value := StrToInt(IniPropStorage1.StoredValue['port']);
MainForm.Left := StrToInt(IniPropStorage1.StoredValue['positionX']);
MainForm.Top := StrToInt(IniPropStorage1.StoredValue['positionY']);
end;procedure TMainForm.FormDestroy(Sender: TObject);
begin
Stream1.Destroy;
TmpImage.Destroy;
BmpImage.Destroy; IniPropStorage1.StoredValue['width'] := IntToStr(MainForm.Width);
IniPropStorage1.StoredValue['height'] := IntToStr(MainForm.Height);
IniPropStorage1.StoredValue['positionX'] := IntToStr(MainForm.Left);
IniPropStorage1.StoredValue['positionY'] := IntToStr(MainForm.Top);
IniPropStorage1.StoredValue['host'] := MainForm.Host.Text;
IniPropStorage1.StoredValue['port'] := IntToStr(MainForm.Port.Value);
IniPropStorage1.Save;
end;procedure TMainForm.TCPSockConnect(aSocket: TLSocket);
begin
StatusBar.SimpleText := 'sending request...';
aSocket.SendMessage('GET /?action=stream' + #10+ #10);
end;procedure TMainForm.TCPSockError(const msg: string; aSocket: TLSocket);
begin
StatusBar.SimpleText := 'connect failed';
ShowMessage(msg);
end;procedure TMainForm.DisplayFrame(stream: TStream);
begin
try
stream.Position:=0;
VideoFrame.Picture.Jpeg.LoadFromStream(stream);
except
StatusBar.SimpleText := 'error while decoding frame!';
exit;
end;
VideoFrame.Repaint;
Application.ProcessMessages;
end;procedure TMainForm.TCPSockReceive(aSocket: TLSocket);
const
SOI : array[0..1] of Byte = ($FF, $D8);
EOI : array[0..1] of Byte = ($FF, $D9);
var
buffer : array[0..65534] of Byte;
search : array[0..1] of Byte;
res, i, j : Integer;
EOIPos, SOIPos, leftover : Int64;
JPEGStream : TMemoryStream;
leftoverStream : TMemoryStream;
begin
res := aSocket.Get( buffer[0], sizeof(buffer) );
if res = 0 then exit; StatusBar.SimpleText := 'received bytes: '+IntToStr(res);
Stream1.Write(buffer[0], res); for i := res downto 0 do begin
Stream1.Position := Max(Stream1.GetSize-1-i, 0);
res := Stream1.Read(search[0], sizeof(search)); if (search[0] = EOI[0]) and (search[1] = EOI[1]) then begin
EOIPos := Stream1.Position-sizeof(search); for j := 0 to EOIPos do begin
Stream1.Position := j;
Stream1.Read(search[0], sizeof(search));
if (search[0] = SOI[0]) and (search[1] = SOI[1]) then begin
SOIPos := Stream1.Position-sizeof(search); Stream1.Position := SOIPos; JPEGStream := TMemoryStream.Create;
JPEGStream.CopyFrom(Stream1, EOIPos+sizeof(EOI)-SOIPos);
DisplayFrame(JPEGStream);
JPEGStream.Destroy; leftover := Stream1.GetSize - (EOIPos + sizeof(EOI));
leftoverStream := TMemoryStream.Create;
if leftover > 0 then begin
Stream1.Position := EOIPos + sizeof(EOI);
leftoverStream.CopyFrom(Stream1, leftover);
end else begin
end;
Stream1.Destroy;
Stream1 := leftoverStream; break;
end;
end; break;
end;
end;
end;initialization
{$I main.lrs}
end.
void CClient_testDlg::OnButton1()
{
// TODO: Add your control notification handler code here
const int bufLen = 65535;
char recBuf[bufLen]={0};
//char buf[10]={0};
sock = socket(AF_INET,SOCK_STREAM,0); sockAddr.sin_addr.s_addr = inet_addr("192.168.1.6");//("127.0.0.1");
sockAddr.sin_port = htons(8080);
sockAddr.sin_family = AF_INET; connect(sock,(SOCKADDR*)&sockAddr,sizeof(sockAddr));
recv(sock,recBuf,bufLen,0); MessageBox(recBuf); closesocket(sock);
}
res := aSocket.Get( buffer[0], sizeof(buffer) );来获取从socket中的数据(应该没有错吧,我对Delphi并不了解)。问题就这样产生了,为什么与服务器建立了连接之后,使用recv()函数,却始终读不到数据呢?要说我的VC程序,那就一个简单就可以概括。 源代码就贴在Delphi代码的后面吧。之前一直没有贴过代码,现在使用添加源码的功能,希望不要出什么错误,方便大侠查看代码。unit main;{$mode objfpc}{$H+}interfaceuses
Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
ExtCtrls, StdCtrls, ComCtrls, lNetComponents, lNet, Spin, Math,
IniPropStorage;type { TMainForm } TMainForm = class(TForm)
Connect: TButton;
IniPropStorage1: TIniPropStorage;
StatusBar: TStatusBar;
Stop: TButton;
Host: TEdit;
Video: TGroupBox;
VideoFrame: TImage;
TCPSock: TLTCPComponent;
Port: TSpinEdit; procedure ConnectClick(Sender: TObject);
procedure StopClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure TCPSockConnect(aSocket: TLSocket);
procedure TCPSockError(const msg: string; aSocket: TLSocket);
procedure TCPSockReceive(aSocket: TLSocket);
procedure DisplayFrame(stream: TStream);
private public
Stream1: TMemoryStream;
end; var
MainForm: TMainForm;
TmpImage : TJPEGImage;
BmpImage : TBitmap;implementation{ TMainForm }function ByteToHex(InByte:byte):shortstring;
const Digits:array[0..15] of char='0123456789ABCDEF';
begin
result:=digits[InByte shr 4]+digits[InByte and $0F];
end;procedure TMainForm.ConnectClick(Sender: TObject);
begin
Stream1.SetSize(0);
StatusBar.SimpleText := 'connecting...';
TCPSock.Connect(Host.Text, Port.Value);
end;procedure TMainForm.StopClick(Sender: TObject);
begin
TCPSock.Disconnect;
StatusBar.SimpleText := 'stopped';
end;procedure TMainForm.FormCreate(Sender: TObject);
begin
Stream1 := TMemoryStream.Create;
TmpImage := TJPEGImage.Create;
BmpImage := TBitmap.Create;
Video.DoubleBuffered:=True; IniPropStorage1.Restore;
MainForm.Width := StrToInt(IniPropStorage1.StoredValue['width']);
MainForm.Height := StrToInt(IniPropStorage1.StoredValue['height']);
MainForm.Host.Text := IniPropStorage1.StoredValue['host'];
MainForm.Port.Value := StrToInt(IniPropStorage1.StoredValue['port']);
MainForm.Left := StrToInt(IniPropStorage1.StoredValue['positionX']);
MainForm.Top := StrToInt(IniPropStorage1.StoredValue['positionY']);
end;procedure TMainForm.FormDestroy(Sender: TObject);
begin
Stream1.Destroy;
TmpImage.Destroy;
BmpImage.Destroy; IniPropStorage1.StoredValue['width'] := IntToStr(MainForm.Width);
IniPropStorage1.StoredValue['height'] := IntToStr(MainForm.Height);
IniPropStorage1.StoredValue['positionX'] := IntToStr(MainForm.Left);
IniPropStorage1.StoredValue['positionY'] := IntToStr(MainForm.Top);
IniPropStorage1.StoredValue['host'] := MainForm.Host.Text;
IniPropStorage1.StoredValue['port'] := IntToStr(MainForm.Port.Value);
IniPropStorage1.Save;
end;procedure TMainForm.TCPSockConnect(aSocket: TLSocket);
begin
StatusBar.SimpleText := 'sending request...';
aSocket.SendMessage('GET /?action=stream' + #10+ #10);
end;procedure TMainForm.TCPSockError(const msg: string; aSocket: TLSocket);
begin
StatusBar.SimpleText := 'connect failed';
ShowMessage(msg);
end;procedure TMainForm.DisplayFrame(stream: TStream);
begin
try
stream.Position:=0;
VideoFrame.Picture.Jpeg.LoadFromStream(stream);
except
StatusBar.SimpleText := 'error while decoding frame!';
exit;
end;
VideoFrame.Repaint;
Application.ProcessMessages;
end;procedure TMainForm.TCPSockReceive(aSocket: TLSocket);
const
SOI : array[0..1] of Byte = ($FF, $D8);
EOI : array[0..1] of Byte = ($FF, $D9);
var
buffer : array[0..65534] of Byte;
search : array[0..1] of Byte;
res, i, j : Integer;
EOIPos, SOIPos, leftover : Int64;
JPEGStream : TMemoryStream;
leftoverStream : TMemoryStream;
begin
res := aSocket.Get( buffer[0], sizeof(buffer) );
if res = 0 then exit; StatusBar.SimpleText := 'received bytes: '+IntToStr(res);
Stream1.Write(buffer[0], res); for i := res downto 0 do begin
Stream1.Position := Max(Stream1.GetSize-1-i, 0);
res := Stream1.Read(search[0], sizeof(search)); if (search[0] = EOI[0]) and (search[1] = EOI[1]) then begin
EOIPos := Stream1.Position-sizeof(search); for j := 0 to EOIPos do begin
Stream1.Position := j;
Stream1.Read(search[0], sizeof(search));
if (search[0] = SOI[0]) and (search[1] = SOI[1]) then begin
SOIPos := Stream1.Position-sizeof(search); Stream1.Position := SOIPos; JPEGStream := TMemoryStream.Create;
JPEGStream.CopyFrom(Stream1, EOIPos+sizeof(EOI)-SOIPos);
DisplayFrame(JPEGStream);
JPEGStream.Destroy; leftover := Stream1.GetSize - (EOIPos + sizeof(EOI));
leftoverStream := TMemoryStream.Create;
if leftover > 0 then begin
Stream1.Position := EOIPos + sizeof(EOI);
leftoverStream.CopyFrom(Stream1, leftover);
end else begin
end;
Stream1.Destroy;
Stream1 := leftoverStream; break;
end;
end; break;
end;
end;
end;initialization
{$I main.lrs}
end.
void CClient_testDlg::OnButton1()
{
// TODO: Add your control notification handler code here
const int bufLen = 65535;
char recBuf[bufLen]={0};
//char buf[10]={0};
sock = socket(AF_INET,SOCK_STREAM,0); sockAddr.sin_addr.s_addr = inet_addr("192.168.1.6");//("127.0.0.1");
sockAddr.sin_port = htons(8080);
sockAddr.sin_family = AF_INET; connect(sock,(SOCKADDR*)&sockAddr,sizeof(sockAddr));
recv(sock,recBuf,bufLen,0); MessageBox(recBuf); closesocket(sock);
}
感谢大牛的帮助,只是问题我实在是没法解决。
我老师给我找了个棘手的事,给了我一块ARM板,ARM板启动之后里头的服务器进程会自动启动,然后就是如上Delphi的代码,还有个用如上Delphi代码编译出来的程序,用该程序确实可以接收到ARM板发送的数据。所以,希望能从Delphi程序中找出其通讯的方式。如果搞不定的话,就只能再去写v4l的程序了。