delphi 7 的socket问题请教

ymenking 2012-09-01 01:31:15
客户端通过socket发送一个图片给服务器端,服务器端判断是否接收完毕时,判断如果接收完毕后,就调用另一个函数处理图片,请问在判断图片接收完毕这里,怎么写调用另一个函数呢,我现在在socketread 里面,在判断接收完毕语句后面加上处理图片的函数,出现二种情况,一种同一张图片接收,由于需要多次接收才接收完毕,从而调用多次图片处理函数,另一种情况就是接收不正常,
请问该怎么写才对呢,我只需要调用一次处理函数,调用多次就会出错。
...全文
191 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
qnaqbgss 2012-09-04
  • 打赏
  • 举报
回复
看下群里的那个DEMO,测试下看看。理论上JPG和BMP任意大小都支持
ymenking 2012-09-03
  • 打赏
  • 举报
回复
我自已还是写不出比较完美的解决方案,由于图片大小是固定的,每次流的传输,流的大小也是固定的,所以我现在是直接写死了流的大小,对于手上的小软件,不考虑以后扩展,是可以用的,如果软件需求变了,就没法用了,先用着吧,非常多谢大家的热心指导。再次感谢
僵哥 2012-09-02
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 的回复:]

建议将图片转成字符格式数据上传,或通过XML格式上传。
[/Quote]
完全是误导。BMP图片作为二进制数据本身就还有很大的可压缩空间,并且在实用传输性能上来说已经是非常不合适的一种编码信息了(简单的针对BMP的压缩就可以在极小运算代价的基础上大幅提升传输效率)。如果将图片转换成字符格式,试问怎么转?XML对图片资源采用的是B64编译,就需要增加1/3的传输量,还需要进行编码和解码的运算消耗。你这方案叫什么?“为用而用”,即为了使用XML而使用XML。一个没有明确目标的设计就是画蛇添足,有一个词叫“垃圾设计”。
lyhoo163 2012-09-02
  • 打赏
  • 举报
回复
建议将图片转成字符格式数据上传,或通过XML格式上传。
僵哥 2012-09-02
  • 打赏
  • 举报
回复
这个通讯协议就有一定的问题,发了一个起始标识,也有一个结束标识,但是这个结束标识很有可能在图片数据当中出现,因为在接收端不能通过'E'#0来判断是否结束,要么在前面增加一个总长度标识,如果确定是BMP也可以通过先接收BMP头,然后通过BMP头里面的图片大小来判断。
ymenking 2012-09-02
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 的回复:]

这样不就行吗
ok:=TMemoryStream.Create;
self.img1.Picture.Graphic.SaveToStream(ok);

取的话,要判断图的类型
如果是jpg的图,img2.picture.graphic:=tjpegimage.create;
如果是BMP的图,img2.picture.graphic:=tbitmap.create;
ok.……
[/Quote]

是BMp的图,是在img控件上面,逐个像素点绘制出来的。
qnaqbgss 2012-09-02
  • 打赏
  • 举报
回复
这样不就行吗
ok:=TMemoryStream.Create;
self.img1.Picture.Graphic.SaveToStream(ok);

取的话,要判断图的类型
如果是jpg的图,img2.picture.graphic:=tjpegimage.create;
如果是BMP的图,img2.picture.graphic:=tbitmap.create;
ok.position:=0;
然后img2.Picture.Graphic.LoadFromStream(ok);
ymenking 2012-09-01
  • 打赏
  • 举报
回复
接收文件的判断:用的是serversocket

else if Copy(Buffer, 1, 4) = 'file' then
begin
FStream.Clear;
if Buffer[Size - 1] = 'E' then
begin
FStream.Write(Buffer[4], Size - 5);
WriteLog('接收文件完毕,大小:' + IntToStr(FStream.Size));
FStream.SaveToFile(ExtractFilePath(Application.ExeName)+'haha.bmp');
img1.Picture.LoadFromFile('haha.bmp');
end
else
FStream.Write(Buffer[4], Size - 4);
end
else
begin
if Buffer[Size - 1] = 'E' then
begin
FStream.Write(Buffer^, Size - 1);
WriteLog('接收文件完毕,大小:' + IntToStr(FStream.Size));
FStream.SaveToFile(ExtractFilePath(Application.ExeName)+'haha.bmp');
img1.Picture.LoadFromFile('haha.bmp');
end
else
FStream.Write(Buffer^, Size);
end;
list.Free;
FreeMem(Buffer);
end;

上面的代码还有一个问题,就是接收后,我用img1.picture.bitmap.loadfromstream(fstream); 图片会载不进img1,原因是什么,一直找不出来,请各位朋友指点一下。


客户端发送图片代码片段:clientsocket:
FStream.Clear;
img1.Picture.Bitmap.SaveToFile(getloadpath+inttostr(getcurrentprocessid)+'.bmp');
fstream.LoadFromFile(getloadpath+inttostr(getcurrentprocessid)+'.bmp');
//img1.Picture.Bitmap.SaveToStream(fstream);
FStream.Position := 0;
Size := FStream.Size;
Inc(Size, 5);
GetMem(Buffer, Size + 1);
FStream.Read(Buffer[4], Size - 5);

Buffer[0] := 'f';
Buffer[1] := 'i';
Buffer[2] := 'l';
Buffer[3] := 'e';
Buffer[Size - 1] := 'E';
Buffer[Size] := #0;
ClientSocket1.Socket.SendBuf(Buffer^, Size);
FreeMem(Buffer);
end;

客户端这里也是有同样的问题,我不懂怎么直接把image的图片载入到TMemoryStream中,我用代码这样写,会没有效果:img1.Picture.Bitmap.SaveToStream(fstream);
kaikai_kk 2012-09-01
  • 打赏
  • 举报
回复
你的问题是判断接收是否完成不正确,可以根据文件大小判断
发送数据前先发送文件大小给对方,然后再分包发送数据(比如每次1k),接收方每接收到一个包就判断一下
  • 打赏
  • 举报
回复
那你应该先说明你用的什么控件,然后贴出部分关键代码,才能知道你的代码错误在哪……
ymenking 2012-09-01
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]

你为什么不写在完成事件里面。。。
[/Quote]
请问怎么写呢,真心不懂,所有东西都是完全自学的,想进公司系统的跟人学习一下,也没什么机会
  • 打赏
  • 举报
回复
你为什么不写在完成事件里面。。。

16,748

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 语言基础/算法/系统设计
社区管理员
  • 语言基础/算法/系统设计社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧