我希望实现的功能是,当服务器端接收到来自客户端的信号I时,会把服务器端的图象发送至客户端,每次发送512,可是实现的时候遇见了以下问题。我的bufsize定义为常量512,这样,会提示出现socket#10040,message too long
是不是我的分包不对呢?多谢各位。
小女子拜谢了。
procedure TForm1.Button1Click(Sender: TObject);var
  FileName:string;   //文件名
  ms:TMemorystream; //内存流变量
  bmp:TBitMap;//图片变量
  sendbuf:array [0..bufsize-1] of char;
  leftsize:Longint;// 剩余大小
begin
  if Edit1.Text = 'I' then
    // 以下为图象的处理与传送
   begin
    try
    FileName:='dd.bmp';
    bmp:=TBitMap.Create ;
    bmp.LoadFromFile(FileName);
        try
        ms:=TMemorystream.Create ;
        bmp.SaveToStream(ms);
            ms.Position :=0;
            leftsize:=ms.Size ;
            if ms.Size = 0 then
              showmessage('no pics or blank!')
            else
            //以下把图象存至缓存区,发送;
              begin
                while leftsize>0 do
                  begin
                  if leftsize>=512 then
                    begin
                      ms.ReadBuffer(sendbuf,bufsize);
                      IDUDPServer1.SendBuffer('127.0.0.1',1011,sendbuf,bufsize);
                      leftsize:=leftsize-bufsize;
                    end
                  else
                    begin
                      ms.ReadBuffer(sendbuf,leftsize);
                      IDUDPServer1.SendBuffer('127.0.0.1',1011,sendbuf,leftsize);
                      leftsize:=leftsize-leftsize;
                    end;
                  end;
              end;
        finally
          ms.Free ;
        end;
    finally
       bmp.Free ;
    end;
   end
   else   showmessage('wrong');
end;

解决方案 »

  1.   

    用Indy吧。Delphi 6 的D:\Program Files\Borland\Delphi6\Demos\Indy\UPDClientServer有个例子。
      

  2.   

    我用的delphi7,indy里面不知为什么是空的。我不知道上面的程序到底怎么错了,前辈能看一下吗?
      

  3.   

    刚刚搜索了所有的相关udp的资料,还是没搞懂,是我问的不清楚吗?急死偶了。
      

  4.   

    你如果用的是TCP就不需要这样麻烦.提示是说你的消息太长.建议你将那个 Buffersize 加大.反正你就一张BMP图压缩成 JPG再传送.不要做分包.发个例子看一下.发送方;
    procedure TForm1.Button1Click(Sender: TObject);
    var streams:tmemorystream;
        newbitmap:tbitmap;
    begin
    streams:=tmemorystream.create;
    newbitmap:=tbitmap.create;
    try
      newbitmap.loadfromfile('dd.bmp');
        with tjpegimage.create do
          begin
          assign(newbitmap);
          CompressionQuality:=65;
          Compress;
          savetostream(streams);
          free;
          end;
       mainform.udpclient.SendBuffer(streams.memory^,streams.size);
    finally
     freeandnil(newbitmap);
     freeandnil(streams);
    end;
    end;
    接收方...procedure TMainForm.UDPServerUDPRead(Sender: TObject; AData: TStream;
      ABinding: TIdSocketHandle);
    begin
    AData.Seek(0, soFromBeginning);
    jpgs:=tjpegimage.Create;
    try
    jpgs.LoadFromStream(AData);
    image1.Picture.Assign(jpgs);
    finally
    freeandnil(jpgs);
    end;
    end;
      

  5.   

    我的bufsize定义为常量512,这样,会提示出现socket#10040,message too long
    是不是我的分包不对呢?
    bufsize定义为常量512-------------多一些。
      

  6.   

    谢谢 manjel(奕 华) ,这样做我真的实现了,,,
    太感谢了。
    --------------------------------------------
    可是我还有疑问,希望大家能给我解答,因为我第一次做这方面的,涉及到很多概念不清晰的地方,现在我还有以下问题,菜是菜,希望大家可以帮我澄清概念。小女子再次拜谢了。1。如果像 manjel(奕 华) 说的这样写的话,我试了,图像稍微大一些的话还是有问题的,当然这可以通过改变CompressionQuality来实现,是吗?我确实把图片质量改的很低,但是效果真的差很多,难道一定没法分包了?2。其实我的本意是把服务器端的图片发送到客户端,但是呢,客户端也会有信息发送到服务器端,在IdUDPclient的方法中,没有直接像IdUDPserver的onread方法,我查看了IdUDPclient的帮助,有这样一个函数
    function ReceiveBuffer(var ABuffer; const ABufferSize: Integer; const AMSec: Integer = IdTimeoutDefault): integer; overload;
    然后帮助中又提到了IdUDPBase,至此,我彻底不知道改怎么使用这个函数了;请达人赐教。3。我现在在这样想,
    我在客户端使用IDUdpclient组件,在服务器端使用IDUdpserver组件,
    以下是我构想的通信过程(因为没有实现嘛,这能构想了)    a。我的客户端先给服务器端发送一个信号,这样我可以在客户端放一个button触发这个事件,在服务器端可以用 OnUDPRead来接收这个信号,(这个我实现了)    b。当服务器端接收到这个信号之后,根据信号发送图像至客户端,这时可以用它的sendbuf来发送图片转化过来的tmemorystream,(这个在分包的时候我不知实现了没有,因为单步执行的结果我没看到,有些笨但是不分包的话也确实可以实现)    c。接下来,我就不太清楚了,我的客户端需要接收图像,正如问题2中我所不清楚的,IDUdpclient组件没有onudpread的方法,我想请问,是应该通过在客户端也放一个IDUdpServer组件来实现呢,还是调用function ReceiveBuffer(): integer; overload;这个函数来实现数据接收呢,但是怎么调用,我真的不会我彻底迷糊了。。我想我问的确实是很基础的问题,
    希望大家能帮我弄清楚这些概念问题,谢谢了。当然会加分了
      

  7.   

    1.不管什么,先压了再说,然后分成一个一个udp数据包(编上序号)送出去
    2.加个线程读
    3.同2
      

  8.   

    当你每次发送的数据大于了那个 Buffersize 就会有这样的提示.Buffersize 如果你设到 655360 就是 640KB 我想一张压缩过的JPG应该不会超过这个数.
    当然什么事都有例外情况.在不明确文件大小的情况下是应该自己分包发送的.你之前的代码.要改一下才能行.但是最好做成 一问一答的模式.就是当你发了一个数据包后最好要等待对方给你一个收到的确认信息再发下一个数据分包.不然可能有问题.而且接收方也要自己组织收到的数据.UDP基本上都是这样的了.如果你用的是TCP就不需要你自己去分包.
      

  9.   

    真是太感谢manjel(奕 华)gg了,不过现在没法上qq,我上了就会加你,你再给我解答问题哦:)回去研究去,,,也谢谢大家。拜~