Antichat снова доступен.
Форум Antichat (Античат) возвращается и снова открыт для пользователей.
Здесь обсуждаются безопасность, программирование, технологии и многое другое.
Сообщество снова собирается вместе.
Новый адрес: forum.antichat.xyz
 |
Проблем с передачей файла в потоках |

25.09.2008, 20:57
|
|
Постоянный
Регистрация: 05.05.2006
Сообщений: 743
Провел на форуме: 2982851
Репутация:
107
|
|
Проблем с передачей файла в потоках
Передающая сторона
Код:
void thr(void *Pvoid)
{WSASetLastError(0);
SOCKET s;SOCKADDR_IN adr;DWORD rb;unsigned long ss,sz;int p=1;
WSADATA wsd;WSAStartup(MAKEWORD(1,1),&wsd);
adr.sin_family=AF_INET;
adr.sin_port=htons(3060);
adr.sin_addr.s_addr=inet_addr("127.0.0.1");
s=socket(AF_INET,SOCK_STREAM,0);
connect(s,(sockaddr*)&adr,sizeof(adr));SetLastError(0);
HANDLE f=CreateFile(fnam,GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_FLAG_RANDOM_ACCESS,0);
char *buf=new char[(1024*1024)*10];
DWORD e=GetFileSize(f,&ss);
if(e>0){sz=e;}if(e<1){sz=ss;}
if(sz<(1024*1024)*10)
{ReadFile(f,buf,sz,&rb,0);send(s,buf,rb,0);}
if(sz>(1024*1024)*10)
{
for(;;)
{
ReadFile(f,buf,(1024*1024)*10,&rb,0);
sz=sz-(1024*1024)*10;send(s,buf,rb,0);
memset(buf,NULL,(1024*1024)*10);MessageBox(0,CurrToStr((int)WSAGetLastError()).c_str(),"!!!",MB_OK);
SetFilePointer(f,((1024*1024)*10)*p,NULL,FILE_BEGIN);p++;
if(sz<(1024*1024)*10){ReadFile(f,buf,sz,&rb,0);send(s,buf,strlen(buf),0);break;}
}
}
}
Принимающая сторона
Код:
void loader(void *Pvoid)
{
SOCKET s,s1;WSADATA wsd;SOCKADDR_IN ladr,adr;DWORD bw;
WSAStartup(MAKEWORD(1,1),&wsd);
ladr.sin_family=AF_INET;
ladr.sin_port=3060;
ladr.sin_addr.s_addr=inet_addr(0);
s=socket(AF_INET,SOCK_STREAM,0);
bind(s,(sockaddr*)&ladr,sizeof(ladr));int sz=sizeof(adr);
listen(s,1);s1=accept(s,(sockaddr*)&adr,&sz);
char *buf=new char[(1024*1024)*10];InitializeCriticalSection(&cs1);
EnterCriticalSection(&cs1);
HANDLE f=CreateFile(outf,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_FLAG_RANDOM_ACCESS,0);
LeaveCriticalSection(&cs1);int szc;
for(;;)
{
szc=recv(s1,buf,(1024*1024)*10,0);MessageBox(0,CurrToStr(szc).c_str(),"!!!",MB_OK);
if(szc<=0){break;}
WriteFile(f,buf,szc,&bw,NULL);
memset(buf,NULL,(1024*1024)*10);Sleep(100);
}CloseHandle(f);
}
Немогу понять по чему неработает  На передающей стороне WSAGetLastError вовращает 10057(тоесть WSAENOTCONN) .Но как такое может быть если при запуске передающего потока в принимающем срабатывает accept 
|
|
|

26.09.2008, 00:26
|
|
Участник форума
Регистрация: 20.12.2007
Сообщений: 295
Провел на форуме: 1777055
Репутация:
347
|
|
тут много неправильного.
Про отдающую сторону:
структуру SOCKADDR_IN надо обнулить перед использованием (точнее некоторые ее поля)
Код:
DWORD e=GetFileSize(f,&ss);
if(e>0){sz=e;}if(e<1){sz=ss;}
в переменную ss вообще-то записывается старшая часть 64-битного размера файла, и смысл приведенных операций не совсем ясен
потом неправильно организован цикл чтения и выдачи файла. Например вот так неправильно
Код:
ReadFile(f,buf,(1024*1024)*10,&rb,0);
sz=sz-(1024*1024)*10;send(s,buf,rb,0);
во-первых вовсе не факт что ReadFile прочтет именно 10 кб данных и никак не меньше. Во-вторых совсем не обязательно что send отправит именно столько данных сколько ему передали а не меньше
Зачем здесь вызывается функция SetFilePointer непонятно.
еще там используется strlen для бинарных данных, что никак недопустимо
с принимающей стороной все еще хуже ошибок очень много
|
|
|

26.09.2008, 01:00
|
|
Постоянный
Регистрация: 05.05.2006
Сообщений: 743
Провел на форуме: 2982851
Репутация:
107
|
|
Во 1х вопрос был именно о проблеме с сокетами а не о других участках клда.
Во 2х если ненравится то предлагаем свой вариант а не критикуем "ваш код плох,а где то есть лутчше"
В 3х с принимающей стороны WSAGetLastError вернуло WSAENOTSOCK
Порылся глубже.Оказывается ноги растут от WSAEADDRNOTAVAIL на bind свмотрю внимательней вроде как не доглядел ladr.sin_port=3060; а надо ladr.sin_port=htons(3060); Думаю заработает.Не тут то было всеравно упорно выдает WSAEADDRNOTAVAIL 
Методом шаманского тыка обнаружил странную вещь если сделать так ladr.sin_addr.s_addr = inet_addr("127.0.0.1"); то работает.Но почему не катят не inet_addr(INADDR_ANY) не inet_addr(0) ??
Последний раз редактировалось _nic; 26.09.2008 в 01:43..
|
|
|

26.09.2008, 07:49
|
|
Участник форума
Регистрация: 20.12.2007
Сообщений: 295
Провел на форуме: 1777055
Репутация:
347
|
|
насчет принимающей стороны
опять же не обнулил структуру ladr.
что касается адреса хоста попробуй так:
Код:
ladr.sin_addr.s_addr=0;
с критическими секциями я конечно могу ошибаться но мне кажется что там они ни к чему
вообще, если ты собираешься просто передавать файл то рекомендуется отправлять его с помощью TransmitFile, это намного легче...
|
|
|

26.09.2008, 20:43
|
|
Постоянный
Регистрация: 05.05.2006
Сообщений: 743
Провел на форуме: 2982851
Репутация:
107
|
|
Сообщение от bons
Код:
ladr.sin_addr.s_addr=0;
О вот так все работает  Спасибо.
ЗЫ:мой код без TransmitFile и так нормально работает файлы передаются ,мд5сумм такого файла совпадает с мд5суммой исходного файла
|
|
|
|
 |
|
Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
|
|
|
|