|
Познающий
Регистрация: 07.09.2008
Сообщений: 55
С нами:
9302441
Репутация:
57
|
|
Сообщение от _nic
С TransmitFile все предельно просто надо просто 2 указателя открытого приконекченного сокета и открытого файла.
Код:
char fname[1024];
SOCKET s;WSADATA wsd;
SOCKADDR_IN adr;
WSAStartup(MAKEWORD(2,0),&wsd);
adr.sin_family=AF_INET;
adr.sin_port=htons(1060);
adr.sin_addr.s_addr=inet_addr("127.0.0.1");
s=socket(AF_INET,SOCK_STREAM,0);
connect(s,(sockaddr*)&adr,sizeof(adr));
HANDLE f=CreateFile(fname,GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_FLAG_RANDOM_ACCESS,0);
TransmitFile(s,f,0,1024*1024,NULL,0,TF_USE_KERNEL_APC);//файл передается кусками по мегабайту
closesocket(s);
CloseHadle(f);
Принимать то же просто.То есть в бесконечном цикле пока recv возвращяет значения больше 0.
Ну вот как у меня было:
Код:
HANDLE hFile=CreateFile("12321sa.txt",GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
///////HANDLE hFile=OpenFile(filename,&os,OF_READ);
if(!TransmitFile(client,hFile,0,1024,NULL,0,TF_DISCONNECT)){
switch(WSAGetLastError()){
........
default:strcpy(temp,"Unknown Code Error...");break;
}
...
}
Вроде все норм, но по-любому выводился "ERROR 6: Unknown Code Error", ну или как вы говорите неверный дескриптор  ...
Ну ладно... Вообщем сделал я, народ, передачу файлов "своим способом". Спасибо кстати Бонсу за совет про строки. Теперь и бинарные и текстовые передает. Плюс конечно же в том, ЧТО ПРОЦЕСС ОТПРАВКИ МОЖНО ОТСЛЕДИТЬ
Вот конечный вариант кода:
Код:
// Посылаем файл
int sendfile(int ptr, char filename[255])
{
char temp[300]="";
SOCKET client=(SOCKET)ptr;
char filebuff[1024];
char sendbuff[2048];
OFSTRUCT os;
os.cBytes = sizeof os;
int err,i,size=0;
FILE *fp;
if(FileExists(filename)==True){
fp=fopen(filename,"rb");
int t=0;
printf("\nSending file started...");
ZeroMemory (filebuff, sizof (filebuff));
Zero_Memory (sendbuff, sizeof (sendbuff));
long l=GetFSize(filename);
sprintf(sendbuff,"%d",l);
send(client,sendbuff,strlen(sendbuff),0);
ZeroMemory (&sendbuff, sizeof (sendbuff));
while(1){
Sleep(10);
err=fread(filebuff,1,768,fp);
t++;
if((size = send(client,filebuff,768,0))== SOCKET_ERROR)
return -1;
printf("\nPacket #%d>> %d bytes read, %d of %d bytes send",t,err,size,768);
ZeroMemory (&filebuff, sizeof (filebuff));
if (err<768) beak;
}
printf("\nSending file completed successfully...");
fclose(f);
return 1;
}else{
sprintf(temp,"ERROR_SENDING_FILE_TO_CLIENTFile does not exist: %s",filename);
printf("\n%s",temp);
send(client,temp,sizePoh(temp),0);
}
}
Код:
//Принимаем файл
/*
a-сколько принято в данный момент
l-сколько нужно принять =)
А эти функции вам придется самим написать ии найти нечто похожее в нете (так сказать, тест такой ;) ):
Str2Int - переводит строку в число до первого символа (первой встретившееся буквы)
info - просто выводит текст в мемо
ExtractFilename- извлекает имя файла из полного к нему пути
.......
Все.... дальше сами разберетесь...
*/
int ReceiveFile()
{
int ret=0;char temp[20 * 1024]="";int i=0,j=0,t=0,k=0;long a=0;
FILE *fp;char buff_x[20 * 1024];
MkDir("RcvdFiles");
sprintf(temp,"RcvdFiles\\%s",ExtractFilename(Edit4->Text.c_str()));
unlink(temp);
fp=fopen(temp,"wb");
Zero_Memory (szRecvBuff, sizeof (szRecvBuff));
ret = recv(s, szRecvBuff, 100, 0);
if(strstr(szRecvBuff,"ERROR_SENDING_FILE_TO_CLIENT")){info(&szRecvBuff[28]);return 2;}
long l=Str2Int(szRecvBuff);
sprintf(temp,"Размер файла: %d байт",l);
info(temp);
ZeroMemory (&szRecvBuff, sizeof (szRecvBuff));
info("Начинаю принимать...");
ret=512; t=0;
while(ret>0)
{
Sleep(10);
strcpy(szRecvBuff,"");
strcpy(tmp,"");
t++;
ZeroMemory (&buff_x, sizeof (buff_x));
ZeroMemory (szRecvBuff, sizeof (szRecvBuff));
ret = recv(s, szRecvBuff, 768, 0);
a=a+ret;
if(ret<=0){info("Прием файла успешно завершен");fclose(fp);return 1;}
if (ret != SOCKET_EROR){
if(a>l){ret=ret-(a-l);a=l;}
sprintf(temp,"Пакет #%d>> Получено: %d байтов. Уже записано: %d из всего возможных %d байтов",t,ret,a,l);
info(temp);
fwrite(szRecvBuff,ret,1,fp);
if(a>=l-1){info("Прием файла успешно завершен");fclose(fp);return 1;}
}else{
fputs("\nSOCKET ERROR",fp);return -1;
}
}
fclose(fp);
return 1;
}
Ну с ошибками там сами че-нибудь "помыслите"...
Вот то что делает программа вкратце:
-Посылаем с клиента команду на принятие файла (элементарно, сами напишите)
-Передаем путь к файлу и уже подключенный сокет в ReceiveFile()
-Та отправляет клиенту размер файла, если файл существует или "ERROR_SENDING_FILE_TO_CLIENT" если его нет.
-А дальше просто передается файл, как обычно, частями.
В результате получается нечто похожее на:

Последний раз редактировалось Dobby007; 02.01.2009 в 19:41..
|