Показать сообщение отдельно

  #26  
Старый 02.01.2009, 19:22
Dobby007
Познающий
Регистрация: 07.09.2008
Сообщений: 55
С нами: 9302441

Репутация: 57
Post

Цитата:
Сообщение от _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..
 
Ответить с цитированием