犹豫再三,我还是决定,把这个帖子发在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);
}

解决方案 »

  1.   

    先看你的connect是否成功,然后你的服务端程序是否发送数据给你客户端,客户端要循环接收数据
      

  2.   


    感谢大牛的帮助,只是问题我实在是没法解决。
    我老师给我找了个棘手的事,给了我一块ARM板,ARM板启动之后里头的服务器进程会自动启动,然后就是如上Delphi的代码,还有个用如上Delphi代码编译出来的程序,用该程序确实可以接收到ARM板发送的数据。所以,希望能从Delphi程序中找出其通讯的方式。如果搞不定的话,就只能再去写v4l的程序了。
      

  3.   

    网络环境初始化了没?看socket成功了没。
      

  4.   

    谢谢各位的帮助,正在自己重新写Linux上的服务端程序,有问题再问大家。