BCB中如何用Socket传送大量数据(如大文件)

毕加索的画 2001-06-14 04:25:00
难道非要分成小块来传吗,有没有别的方法呢?
我用分块传的方法速度好慢,一个5M的文件传完要3分钟
...全文
260 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
毕加索的画 2001-06-16
  • 打赏
  • 举报
回复
怎么回事,大事帮助我呀!
我会给分的!
毕加索的画 2001-06-15
  • 打赏
  • 举报
回复
.
毕加索的画 2001-06-15
  • 打赏
  • 举报
回复
to shally5:
我按你的方法试了一下,速度是快了一些但还远远达不到"200MB的大文件一分钟多"的速度
而且当我用大于70M的文件测试时,会产出"异常",这是怎么回事?

还有能解释一下TClientSocket组件的ClientType属性和TServerSocket的ServerType吗?
阻塞Socket是什么意思?

我一定会给分的!

以下是我的源码:

F_SendFile.h

//---------------------------------------------------------------------------

#ifndef F_SendFileH
#define F_SendFileH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <Dialogs.hpp>
#include <ScktComp.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
TButton *btnConn;
TButton *btnDisconn;
TClientSocket *ClientSocket;
TServerSocket *ServerSocket;
TOpenDialog *OpenDialog1;
void __fastcall btnConnClick(TObject *Sender);
void __fastcall ClientSocketConnect(TObject *Sender,
TCustomWinSocket *Socket);
void __fastcall ServerSocketClientRead(TObject *Sender,
TCustomWinSocket *Socket);
void __fastcall ClientSocketRead(TObject *Sender,
TCustomWinSocket *Socket);
private: // User declarations
TFileStream* FileRead;
TFileStream* FileWrite;
int iStepServ,iStep;
int iFileLen;
int ReceiveLen;
public: // User declarations
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif




F_SendFile.cpp

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "F_SendFile.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
iStep = 0;
iStepServ = 0;
ReceiveLen = 0;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::btnConnClick(TObject *Sender)
{
ClientSocket->Open();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ClientSocketConnect(TObject *Sender,
TCustomWinSocket *Socket)
{
if(!OpenDialog1->Execute())
return;
FileRead = new TFileStream(OpenDialog1->FileName,fmOpenRead);
int ifsz = FileRead->Size;
Socket->SendBuf(&ifsz,sizeof(int));
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ServerSocketClientRead(TObject *Sender,
TCustomWinSocket *Socket)
{
if(iStepServ == 0)
{
Socket->ReceiveBuf(&iFileLen,sizeof(int));
++iStepServ;
Socket->SendText("@Send!");
FileWrite = new TFileStream("D:\\test.swp",fmOpenWrite|fmCreate|fmShareExclusive);
return;
}
if(iStepServ == 1)
{
char* pfbuf = new char[iFileLen];
int iRealSize = Socket->ReceiveBuf(pfbuf, iFileLen);
FileWrite->Write(pfbuf, iRealSize);
ReceiveLen += iRealSize;
if(ReceiveLen == iFileLen)
{
delete FileWrite;
iStepServ = 0;
Socket->SendText("@Transmission completed!");
}
delete []pfbuf;
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ClientSocketRead(TObject *Sender,
TCustomWinSocket *Socket)
{
if(iStep == 0)
{
if(Socket->ReceiveText() == "@Send!")
{
++iStep;
Socket->SendStream(FileRead);
return;
}
}
if(iStep == 1)
{
if(Socket->ReceiveText() == "@Transmission completed!")
{
iStep = 0;
}
}
}
coolcalf 2001-06-15
  • 打赏
  • 举报
回复
学习
rabbitisme 2001-06-15
  • 打赏
  • 举报
回复
精彩精彩……鼓掌鼓掌!

怎么不加分呢?可惜我不能给你呀!呵呵!
shally5 2001-06-15
  • 打赏
  • 举报
回复
发送流程如下
发送方:
1.以文件流方式打开文件
fs_read = new TFileStream(Edit4->Text,fmOpenRead);
2.取文件长度
file_len = fs_read->Size;
3.将文件长度发给对方
ClientSocket_LEN->Socket->SendText(file_len);
4.等对方回应-1?是的话就发文件
astemp = Socket->ReceiveText();
if(StrToInt(astemp)==-1) then
ClientSocket_FILE->Socket->SendStream(fs_read);
5.接收到Transmission completed!字符后关闭文件


接收方:
1.收到的文件长度并打开文件
astemp = Socket->ReceiveText();
fs_write = new TFileStream(Edit7->Text,fmOpenWrite|fmCreate|fmShareExclusive);
2.发送-1
ServerSocket_LEN->Socket->SendText("-1");
3.接收数据
void * pvbuf;
int isize,irealsize;
isize = Socket->ReceiveLength();
pvbuf = malloc(isize);
irealsize = Socket->ReceiveBuf(pvbuf,isize);
fs_write->Write(pvbuf,irealsize);
receive_len += irealsize;
if (receive_len == receive_filelen)
{
FileClose(fs_write->Handle);
ServerSocket_FILE->Socket->SendText("Transmission completed!");
}
free(pvbuf);
毕加索的画 2001-06-15
  • 打赏
  • 举报
回复
to Raptor(猛禽)
能把你的源代码贴出来看看吗?
不方便的话只要发送/接收部分也行!
我的源码在:
http://wzgshow.yeah.net中
毕加索的画 2001-06-15
  • 打赏
  • 举报
回复
to Raptor(猛禽)
能把你的源代码贴出来看看吗?
不方便的话只要发送/接收部分也行!
猛禽 2001-06-14
  • 打赏
  • 举报
回复
不会吧,我传2M的文件不到两秒钟(本机SOCKET),100M网内也不超过5S
毕加索的画 2001-06-14
  • 打赏
  • 举报
回复
to nethunter(路人·过客·我)
用内存流发送是用 Socket->SendStream(TStream*) 吗?
毕加索的画 2001-06-14
  • 打赏
  • 举报
回复
我是在本地进程间测试的,每块是2k,
一个块8k,我试过效果不明显。
各位有没有源码,贴上来看看。
nethunter 2001-06-14
  • 打赏
  • 举报
回复
哈哈……
是呀,偶的HTTP服务器大约每分钟可以传10M,在自己的计算机上可以
达到1M/s的极速,如果用内存流发送就更快,可以达到1350k/s的极速。

我是用Socket发送的。
shally5 2001-06-14
  • 打赏
  • 举报
回复
我作过,200MB的大文件一分钟多(两台机器在一个HUB上)没问题啊!
我不懂电脑 2001-06-14
  • 打赏
  • 举报
回复
一个块最好是近似8k,因为一个ip包8k
BCB 2001-06-14
  • 打赏
  • 举报
回复
当然要分块了,块可以10KB,
5*8/180=0.25 Mb/秒
在局域网(10Mbn/s)是有点慢了,肯定有你程序本身有问题

13,873

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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