100分求用ServerClient发送文件程序

sxzqlzx 2009-09-27 12:09:30
开发一个通过互联网发送文件的程序,要传送到内网,屡试不成,有完整的程序的朋友发一个。NMStrmServ只能指到出口IP上,指不到内网IP。

邮箱sxzqlzx@163.com。 能用立刻结贴。
...全文
265 18 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
xjq2003 2009-11-19
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 wewaa 的回复:]
C/C++ code一个简单的传输的例子 单线程 阻塞模式. 用 bcc32.exe 可直接编译通过.

以下是发送端代码

send.cpp

view plaincopy to clipboardprint?//---------------------------------------------------------------------------
#include<io?-
[/Quote]可以用
pp616 2009-11-19
  • 打赏
  • 举报
回复
只要有一个机器有公网IP 就可以正常发送。
如果2台机器在不同的局域网内 需要UDP穿透。
wseagle 2009-11-16
  • 打赏
  • 举报
回复
期待 chinezwq 的高论 我也遇到了类似的问题
sxzqlzx 2009-10-27
  • 打赏
  • 举报
回复
网络的整体不是很懂,现在做了一个,互联网上速度奇慢,什么原因,不知道。
chinezwq 2009-10-21
  • 打赏
  • 举报
回复
发到公网ip后,通过这个ip进行转发到私网ip不就可以了么,你应该是对网络的整体不是很懂吧
sxzqlzx 2009-10-19
  • 打赏
  • 举报
回复
顶一下,还没有完全解决,谁有非阻塞的传输文件例程,发一个。谢了
僵哥 2009-10-05
  • 打赏
  • 举报
回复
        TMemoryStream* pms = new TMemoryStream(); 
void *p;
pms->LoadFromFile(FileName);
p=malloc(pms->Size);
pms->Position=0;
pms->ReadBuffer(p,pms->Size);
Socket->SendBuf(p,pms->Size);
free(p);
delete pms;


这里的SendBuf需要处理其返回值,即实际发送的字节数.其实这里可以直接SendStream,记得不要把Free掉Stream即可.


AnsiString Flag,FileName,rectxt; 

int nSize = 0;

__int64 i64Len;
i64Len=Socket->ReceiveLength();
if(i64Len <1)return;
// Memo1->Lines->Add(i64Len);
rectxt = Socket->ReceiveText() ;
if(rectxt.Pos("sendfile"))
{
int pos1,pos2;
pos1 = rectxt.Pos(" <");
pos2 = rectxt.Pos(">");
Flag = rectxt.SubString(1,pos1-1);
FileName = rectxt.SubString(pos1+1,pos2-pos1-1);
memLen=StrToInt(rectxt.SubString(pos2+1,rectxt.Length()-pos2));
Memo1->Lines->Add(Flag);
Memo1->Lines->Add(FileName);
Memo1->Lines->Add(memLen);
if(Flag == "sendfile")
Socket->SendText("FileOk");
}
else
{
nSize =1;
do{
nSize = Socket->ReceiveBuf(buf, sizeof(buf));
ReceiveLen = ReceiveLen + nSize ;
Memo1->Lines->Add(IntToStr(nSize) + " + " + IntToStr(ReceiveLen) + " " + IntToStr(memLen));
if (nSize>0 )
FileWrite1->Write(buf,nSize);
} while(nSize>0 );
}


由于没有定义合理的协议,很难知道什么时候数据收齐。仅依赖于ReceiveLength并不能一定一次收完所有内容,所以这个ReceiveLength并不能算是完整的。
sxzqlzx 2009-09-29
  • 打赏
  • 举报
回复
发送
TMemoryStream* pms = new TMemoryStream();
void *p;
pms->LoadFromFile(FileName);
p=malloc(pms->Size);
pms->Position=0;
pms->ReadBuffer(p,pms->Size);
Socket->SendBuf(p,pms->Size);
free(p);
delete pms;

接收

AnsiString Flag,FileName,rectxt;

int nSize = 0;

__int64 i64Len;
i64Len=Socket->ReceiveLength();
if(i64Len<1)return;
// Memo1->Lines->Add(i64Len);
rectxt = Socket->ReceiveText() ;
if(rectxt.Pos("sendfile"))
{
int pos1,pos2;
pos1 = rectxt.Pos("<");
pos2 = rectxt.Pos(">");
Flag = rectxt.SubString(1,pos1-1);
FileName = rectxt.SubString(pos1+1,pos2-pos1-1);
memLen=StrToInt(rectxt.SubString(pos2+1,rectxt.Length()-pos2));
Memo1->Lines->Add(Flag);
Memo1->Lines->Add(FileName);
Memo1->Lines->Add(memLen);
if(Flag == "sendfile")
Socket->SendText("FileOk");
}
else
{
nSize =1;
do{
nSize = Socket->ReceiveBuf(buf, sizeof(buf));
ReceiveLen = ReceiveLen + nSize ;
Memo1->Lines->Add(IntToStr(nSize) + " + " + IntToStr(ReceiveLen) + " " + IntToStr(memLen));
if (nSize>0 )
FileWrite1->Write(buf,nSize);
} while(nSize>0 );
}
为何始终少一个包,接收到的文件比源文件少8192?
sczyq 2009-09-28
  • 打赏
  • 举报
回复
原来两台电脑已经建立连接,试试发送简单指令看看,客户端能否接收到

或许 NMStrmServ 有问题, 我对 NMStrmServ 不熟悉,
sxzqlzx 2009-09-28
  • 打赏
  • 举报
回复
sczyq(>>>>>>>>>>>>>>>) 兄,现在两台电脑已建立连接,serv端可以找到客户端的,现在就想要发送文件的代码,连接不用。
sxzqlzx 2009-09-28
  • 打赏
  • 举报
回复

xpdavis(咕嘟(不再孤独))兄说得对,是想在内网的电脑间发送文件,现在服务器端有固定的IP,客户端访

问,要从服务器端往客户端(内网)发送文件。
laowang2 2009-09-28
  • 打赏
  • 举报
回复
一个简单的传输的例子 单线程 阻塞模式.   用 bcc32.exe 可直接编译通过.

以下是发送端代码

send.cpp

view plaincopy to clipboardprint?
//---------------------------------------------------------------------------

#include <iostream>

#include "winsock2.h"

using namespace std;



#pragma comment(lib , "ws2_32.lib")

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



WSADATA wsaData;

UINT uTimerID;

DWORD MAX_SIZE = 1024 * 4;

DWORD FinishSize = 0;

DWORD SendSize = MAX_SIZE;

LPSTR SFileName;

DWORD FSize;

DWORD DWSpeed=0;

DWORD OldFinish=0;



MMRESULT (WINAPI *ptimeSetEvent)(UINT uDelay, UINT uResolution, LPTIMECALLBACK fptc, DWORD dwUser, UINT fuEvent);

MMRESULT (WINAPI *ptimeKillEvent)(UINT uTimerID);

HINSTANCE DLLInst;



bool init()

{

DLLInst=LoadLibrary("winmm.dll");

if(DLLInst)

{

ptimeSetEvent = (MMRESULT (WINAPI *)(UINT uDelay, UINT uResolution, LPTIMECALLBACK fptc, DWORD dwUser, UINT fuEvent))GetProcAddress(DLLInst, "timeSetEvent");

if(!ptimeSetEvent) return false;

ptimeKillEvent = (MMRESULT (WINAPI *)(UINT uTimerID))GetProcAddress(DLLInst, "timeKillEvent");

if(!ptimeKillEvent) return false;

return true;

}

return false;

}



void Byte2Human(const DWORD & byte)

{

if(byte < 1024){

cout << ((float)((int)(byte*100+0.5))/100.0) << "B";

return;

}

float kb = byte/1024;

if (kb<1024){

cout << ((float)((int)(kb*100+0.5))/100.0) << "KB";

return ;

}

float mb = kb/1024;

if (mb<1024){

cout << ((float)((int)(mb*100+0.5))/100.0) << "MB";

return;

}

float gb = mb/1024;

cout << ((float)((int)(gb*100+0.5))/100.0) << "GB";

}



void WINAPI TimeProc(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)

{

DWSpeed = FinishSize-OldFinish;

OldFinish = FinishSize;

cout << '\r';

cout << " ";

cout << '\r';

cout << "文件名:" << SFileName << " " << FinishSize << "/" << FSize << " ";

Byte2Human(DWSpeed);

cout << "/S";

}



int main(int argc, char* argv[])

{

if(!init())

{

cout<<"初始化失败"<<endl;

return 0;

}

int ret;

if(argc < 4)

{

cout << "App.exe Host Port FileName" << endl;

return 0;

}



if((ret=WSAStartup(0x0202, &wsaData))!=0)

{

cout << "WSAStartup Failed!! Code:" << ret << endl;

return 0;

}

SOCKET sock;

struct sockaddr_in server;

sock=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

if(sock==INVALID_SOCKET)

{

cout << "创建socket出错" << endl;

return 0;

}

server.sin_family=AF_INET;

server.sin_port=htons(atoi(argv[2]));

server.sin_addr.s_addr=inet_addr(argv[1]);

cout << "正在连接 " << argv[1] << ":" << argv[2] << endl;

if(connect(sock, (struct sockaddr *)&server, sizeof(server))==SOCKET_ERROR)

{

cout << "连接失败" << endl;

return 0;

}

cout << "连接成功" << endl;



//打开文件准备发送

HANDLE hFile;

OFSTRUCT ofs;

HANDLE hMap;

void *pVoid;

SFileName = argv[3];

hFile=(HANDLE)OpenFile(argv[3], &ofs, OF_READWRITE | OF_SHARE_DENY_NONE);

if((HFILE)hFile==HFILE_ERROR)

{

cout << "打开文件失败 ErrorCode=" << GetLastError() << endl;

return 0;

}

FSize=GetFileSize((HANDLE)hFile, NULL);

hMap=CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0, NULL);

if(hMap==NULL)

{

cout << "打开映射失败 ErrorCode=" << GetLastError() << endl;

return 0;

}

pVoid=MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);

if(pVoid==NULL)

{

cout << "映射数据失败 ErrorCode=" << GetLastError() << endl;

return 0;

}

char *p = (char *)pVoid;

cout << "正在发送文件 " << argv[3] << endl;

uTimerID=ptimeSetEvent(1000, 0, (LPTIMECALLBACK)TimeProc, NULL, TIME_PERIODIC|TIME_CALLBACK_FUNCTION);



while(1)

{

if(FSize - FinishSize < MAX_SIZE)

{

SendSize = FSize - FinishSize;

}

int ret = send(sock, p+FinishSize, SendSize, 0);

if(ret == SOCKET_ERROR )

{

cout << endl << "Ret=" << ret << " ErrorCode=" << WSAGetLastError() << endl;

return 0;

}

FinishSize += ret;

if(FinishSize == FSize) break;

}

closesocket(sock);

ptimeKillEvent(uTimerID);

CloseHandle(hMap);

CloseHandle(hFile);

cout << endl;

cout << "完成 发送数据量:" << FinishSize << endl;

return 0;

}

//---------------------------------------------------------------------------
AuroraAlpha 2009-09-27
  • 打赏
  • 举报
回复
NM没试过。。。 只会用Indy的。。。
ydlchina 2009-09-27
  • 打赏
  • 举报
回复
内网那个IP,就是分配到每个机器的IP,(大多172或192开头)另外有的是可以自动获取内网地址的
铖邑 2009-09-27
  • 打赏
  • 举报
回复
楼主的意思是两个处于内网的主机之间发送文件?

要给处于内网的主机发送文件必须满足满足一下条件之一:

1、内网的主机能够开放公网地址端口;

2、两个处于内网的主机通过一台公网服务器中转。

楼主把需求理清楚再看看怎么解决吧
sczyq 2009-09-27
  • 打赏
  • 举报
回复
内网接收是Server程序,那就好办了,在路由器上NAT端口。
内网接收是Client程序,那就难办了,没有明确的机器,不知道要去哪。

1,317

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder 网络及通讯开发
社区管理员
  • 网络及通讯开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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