NMUDP发送文件时出现问题。

佛火 2004-11-29 05:50:14
文件采用分包传送,每个包大小1900字节,
struct DATA
{
char action[10];
int ID;
int pcount;
int psize;
int filesize;
char filename[20];
char data[1900];
};
在同一网段时可以正常使用,但是在跨网段的时候就会出现一个奇怪的问题:
假设一个文件a.exe,分为20000个包发送,但是在传送到第4000个包的时候就传不下去了,不管把那个包重新发送多少次都没有反应,也就是对方收不到数据包。重新发送a.exe,每次都是发到第4000个包的时候就发不过去了。但是发送比较小的文件又正常,一般5M以下的文件都正常。
把客户端和服务器端交换,也会出一此问题,并且对于不同的文件,每次停止的包数都不同,有的是1026,有2035,有7755,对同一文件,每次都是相同的位置。
不知道为什么,。。。。。。。。
...全文
135 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
佛火 2004-11-30
  • 打赏
  • 举报
回复
这是个测试程序,主要用来测试UDP发送文件,因为我另外在做一个音乐在线的客户端和服务器,要用到上传和下载功能,所以写个测试程序。
Buffer应该没有问题,因为在本地或者同一网段的计算机(202.193.74.***)都没有问题,只是从我的IP(202.193.74.***)发送的服务器(202.193.70.***)时或者把我自己当服务器,反过来发的时候有问题,同时我还测试了另一台服务器,也是(202.193.70.***)网段的,也会出现同样的问题。
佛火 2004-11-30
  • 打赏
  • 举报
回复
问题已解决
ben3 2004-11-29
  • 打赏
  • 举报
回复
1.用其它软件转送同一文件,先分清是程序还是网络出问题
2.缓存buffer是否有问题
3.改用indy控件

我水平有限,但你的代码很值得参考.
佛火 2004-11-29
  • 打赏
  • 举报
回复
服务器端:

Unit1.h

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

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <NMUDP.hpp>
#include "SUIEdit.hpp"
#include "SUIForm.hpp"
#include "SUIMemo.hpp"
#include <ExtCtrls.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
TNMUDP *server;
TsuiForm *suiForm1;
TsuiEdit *Edit1;
TsuiEdit *Edit2;
TsuiEdit *Edit3;
TsuiEdit *Edit4;
TsuiEdit *ip;
TsuiEdit *port;
void __fastcall serverDataReceived(TComponent *Sender,
int NumberBytes, AnsiString FromIP, int Port);
void __fastcall FormCreate(TObject *Sender);
private: // User declarations
public: // User declarations
__fastcall TForm1(TComponent* Owner);
struct DATA
{
char action[10];
int ID;
int pcount;
int psize;
int filesize;
char filename[20];
char data[1900];
};

int rcount;
int thisid;

};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif


Unit1.cpp

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

#include <vcl.h>
#pragma hdrstop
#include "stdio.h"
#include "Unit1.h"
#include <winsock.h>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "SUIEdit"
#pragma link "SUIForm"
#pragma link "SUIMemo"
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//-----------
AnsiString GetLocalIP()
{
//Start up WinSock
WORD wVersionRequested = MAKEWORD(1,1);;
WSADATA wsaData;
WSAStartup(wVersionRequested, &wsaData);

hostent *p;
char s[128];
char *p2;
gethostname(s,128);//获取指定计算机的名字
p = gethostbyname(s);
p2 = inet_ntoa(*((in_addr *)p->h_addr)); //获取指定计算机的IP地址
WSACleanup();
return p2;
}

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

void __fastcall TForm1::serverDataReceived(TComponent *Sender,
int NumberBytes, AnsiString FromIP, int Port)
{
rcount++;
DATA *Data;
char *Buffer = new char[sizeof(DATA)];
server->ReadBuffer(Buffer,NumberBytes,NumberBytes);
Data = (DATA*)Buffer;
if(Data->ID==1)
thisid=Data->ID;
if(Data->ID==1||Data->ID>thisid)
{
thisid=Data->ID;
Edit2->Text=String("FileName:")+Data->filename;
Edit3->Text=String("Current:")+Data->psize+"Byte";
Edit4->Text=String("ID:")+Data->ID;
FILE *f;
f=fopen((String("F:\\")+Data->filename).c_str(),"a+b");
fseek(f,0,2);
fwrite(Data->data,Data->psize,1,f);
fclose(f);
//Memo1->Text=Data.data;
//ListBox1->Items->Add(Data.ID);
Edit1->Text=IntToStr(rcount)+"/"+IntToStr(Data->pcount);
server->RemoteHost=FromIP;
server->RemotePort=Port;
server->SendBuffer(Buffer,NumberBytes,NumberBytes);
}
delete Buffer;
}
//---------------------------------------------------------------------------


void __fastcall TForm1::FormCreate(TObject *Sender)
{
thisid=0;
ip->Text=GetLocalIP();
port->Text=server->LocalPort;
}
//---------------------------------------------------------------------------





佛火 2004-11-29
  • 打赏
  • 举报
回复
程序源码:
客户端:
Unit1.h

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

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <NMUDP.hpp>
#include <Dialogs.hpp>
#include <ExtCtrls.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
TNMUDP *client;
TButton *Button1;
TEdit *Edit1;
TEdit *Edit2;
TEdit *Edit3;
TOpenDialog *OpenDialog1;
TEdit *Edit4;
TListBox *ListBox1;
TTimer *Timer1;
TEdit *Edit5;
TEdit *Edit6;
TMemo *Memo1;
TEdit *Edit7;
TEdit *Edit8;
TEdit *Edit9;
TEdit *Edit10;
TEdit *Edit11;
TEdit *Edit12;
TEdit *Edit13;
TButton *Button2;
void __fastcall Button1Click(TObject *Sender);
void __fastcall serverDataReceived(TComponent *Sender,
int NumberBytes, AnsiString FromIP, int Port);
void __fastcall FormCreate(TObject *Sender);
void __fastcall clientDataReceived(TComponent *Sender,
int NumberBytes, AnsiString FromIP, int Port);
void __fastcall FormClose(TObject *Sender, TCloseAction &Action);
void __fastcall Timer1Timer(TObject *Sender);
void __fastcall Button2Click(TObject *Sender);
private: // User declarations
public: // User declarations
__fastcall TForm1(TComponent* Owner);
struct DATA
{
char action[10];
int ID;
int pcount;
int psize;
int filesize;
char filename[20];
char data[1900];
};
TFileStream *strm;
int filesize;
int count,rcount;
int max;
int pcount;
int lastpsize;
AnsiString filename;
bool FileEnd;
int badsend;
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif



Unit1.cpp

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

#include <vcl.h>
#pragma hdrstop
#include "stdio.h"
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------


void __fastcall TForm1::Button1Click(TObject *Sender)
{
badsend=0;
count=0;
rcount=0;
client->RemoteHost=Edit12->Text;
client->RemotePort=Edit13->Text.ToInt();
Timer1->Enabled=false;
FileEnd=false;
OpenDialog1->FileName=NULL;
OpenDialog1->Execute();
if(OpenDialog1->FileName!=NULL)
{
DATA Data;
int Buffersize;
char *Buffer = new char[sizeof(DATA)];
strm = new TFileStream(OpenDialog1->FileName,fmOpenRead);
filesize=strm->Size;
pcount = strm->Size / max;
lastpsize = strm->Size % max;
filename=filename=FormatDateTime("m_d_hh_mm_s", Now())+ExtractFileExt(OpenDialog1->FileName);
if(strm->Size>=max)
{
Buffersize=max;
}
else
{
Buffersize=strm->Size;
}
strm->Read(Data.data,Buffersize);
strcpy(Data.action,"Data");
strcpy(Data.filename,filename.c_str());
Data.filesize=strm->Size;
Data.ID=1;
Data.pcount=pcount;
Data.psize=Buffersize;
Buffer = (char *)&Data;
count++;
client->SendBuffer(Buffer,sizeof(DATA),sizeof(DATA));
delete Buffer;
Timer1->Enabled=true;
Edit4->Text=IntToStr(count)+"/"+IntToStr(pcount);
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
badsend=0;
max=1900;
count=0;
rcount=0;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::clientDataReceived(TComponent *Sender,
int NumberBytes, AnsiString FromIP, int Port)
{
Timer1->Enabled=false;
DATA *Data;
char *Buffer = new char[sizeof(DATA)];
client->ReadBuffer(Buffer,NumberBytes,NumberBytes);
Data = (DATA*)Buffer;
if(Data->ID>=1&&Data->ID<=pcount-1&&Data->ID==count)
{
ZeroMemory(Buffer,sizeof(DATA));
memset(Data,0,sizeof(Data));
count++;
strcpy(Data->action,"data");
strcpy(Data->filename,filename.c_str());
strm->Read(Data->data,max);
Data->ID=count;
Data->filesize=filesize;
Data->pcount=pcount;
Data->psize=max;
Buffer=(char *)Data;
client->RemoteHost=Edit12->Text;
client->RemotePort=Edit13->Text.ToInt();
client->SendBuffer(Buffer,sizeof(DATA),sizeof(DATA));
Edit4->Text=IntToStr(count)+"/"+IntToStr(pcount);
Timer1->Enabled=true;
if(Data->ID==pcount-1&&lastpsize==0)
{
FileEnd=true;
Timer1->Enabled=false;
}
}
if(Data->ID==pcount&&lastpsize>0&&!FileEnd)
{
FileEnd=true;
ZeroMemory(Buffer,sizeof(DATA));
memset(Data,0,sizeof(Data));
count++;
strcpy(Data->action,"end");
strcpy(Data->filename,filename.c_str());
strm->Read(Data->data,lastpsize);
Data->ID=count;
Data->filesize=filesize;
Data->pcount=pcount;
Data->psize=lastpsize;
Buffer=(char *)Data;
Edit4->Text=IntToStr(count)+"/"+IntToStr(pcount);
client->RemoteHost=Edit12->Text;
client->RemotePort=Edit13->Text.ToInt();
client->SendBuffer(Buffer,sizeof(DATA),sizeof(DATA));
delete strm;
}
if(!FileEnd)
{
Timer1->Enabled=true;
}
if(Data->ID==1&&Data->psize<max)
{
FileEnd=true;
delete strm;
Timer1->Enabled=false;
}
delete Buffer;

}
//---------------------------------------------------------------------------


void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
//delete strm;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
char *TempBuffer=new char[sizeof(DATA)];
Timer1->Enabled=false;
badsend++;
Edit5->Text="重试"+IntToStr(badsend)+"次,ID:"+IntToStr(count);
ZeroMemory(TempBuffer,sizeof(DATA));
DATA Data;
Data.ID=count;
strcpy(Data.action,"data");
strcpy(Data.filename,filename.c_str());
Data.filesize=filesize;
Data.pcount=pcount;
if(count<=pcount)
{
Data.psize=max;
}
if(count==pcount+1)
{
Data.psize=lastpsize;
}
strm->Seek(-Data.psize,1);
strm->Read(Data.data,Data.psize);
//---------------------
Edit11->Text=Data.action;
Edit10->Text=Data.ID;
Edit7->Text=Data.pcount;
Edit8->Text=Data.filename;
Edit9->Text=Data.filesize;
Memo1->Text=Data.data;
//-----------------------
TempBuffer=(char *)&Data;
client->RemoteHost=Edit12->Text;
client->RemotePort=Edit13->Text.ToInt();
client->SendBuffer(TempBuffer,sizeof(DATA),sizeof(DATA));
delete TempBuffer;
Timer1->Enabled=true;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button2Click(TObject *Sender)
{
Timer1->Enabled=true;
}
//---------------------------------------------------------------------------


1,317

社区成员

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

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