![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
проблемы с Winsock [D7, WinXP]
Foccer © (2009-04-25 11:54:00)Здравствуйте уважаемые.
Я студент. Нам дали задание сделать пару проектов с помощью этой либы(если не ошибаюсь)
одна из задач передача файла посредством протокола UDP
в этой процедуре идет коннект к серверу
procedure TForm1.ConnectBtnClick(Sender: TObject);
begin
// connect to the server
sClient:=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
with ServerAddr do begin
sin_family:=AF_INET;
sin_addr.S_addr:=inet_addr(Pchar(AddrEdit.Text));
sin_port:=htons(45);
end;
if connect(sClient,ServerAddr,sizeof(ServerAddr)) = SOCKET_ERROR
then begin
LogEdit.Lines.Add('Connection failed');
LogEdit.Lines.Add(inttostr(WSAGetLastError));
status:=false;
end
else begin
LogEdit.Lines.Add('Server connected');
status:=true;
end;
end;
а вот в этой процедуре идет отправка файла
procedure TForm1.SendFileBtnClick(Sender: TObject);
var
sFile:TFileStream;
begin
// Send file to the server
sFile.Create(FileEdit.Text,fmOpenRead);
sFile.Position:=0;
if status = true
then begin
LogEdit.Lines.add(BoolToStr(Status));
ret:=send(sClient,sFile,sizeof(sFile),0);
if (ret = SOCKET_ERROR)
then begin
LogEdit.Lines.Add('Send failed');
LogEdit.Lines.Add(IntToStr(WSAGetLastError));
end
else begin
LogEdit.Lines.Add('File send complete');
end;
end
else begin
LogEdit.Lines.Add('The server not connected');
LogEdit.Lines.Add(inttostr(WSAGetLastError));
end;
end;
Собственно сам модуль запуска сервера с помощью баттона
procedure TForm1.StartServerBtnClick(Sender: TObject);
begin
// Start server on this PC (local)
WSAStartup(MakeWord(2,0),WSADATA);
sServer:=Socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
with LocalAddr do begin
sin_family:=AF_INET;
sin_addr.S_addr:=inet_addr(PChar(LocalAddrEdit.Text));
sin_port:=htons(45);
end;
bind(sServer,LocalAddr,sizeof(LocalAddr));
listen(sServer,4);
iSize:=sizeof(LocalAddr);
sClient:=accept(sServer,@LocalAddr,@iSize);
closesocket(sServer);
end;
вроде все правильно
запускаю клиент пишет есть подключение к серверу
но когда нажимаю на отправку файла просто вылетает
ошибка access violation. дальше нуль эмоций.
Прошу подсказать что я пропустил.
Сергей М. (2009-04-28 19:58:00) [1]Лыбу строй преподу)
foccer (2009-04-28 19:41:00) [2]^_^
Сергей М. (2009-04-28 19:23:00) [3]Отладчик в зубы - и вперед !
> не догоняю
За "догон" платить следует.
Готов ?
$500 - и получишь готовое.
foccer (2009-04-28 18:27:00) [4]сервер без неблок режим и селекта
str:=tmemorystream.create;
RecvBytes:=recv(sServer,str.memory^,str.Size,0);
if recvbytes < 0 then begin
LogMemo.Lines.Add('recv error');
break;
closesocket(sServer);
end;
str.SaveToFile('c:\delphi\1.dat');
клиент
total:=0;
while total <= sFile.Size do begin
SentBytes:=sendto(sClient,sFile.memory^,sFile.Size,0,ServerAddr,sizeof(ServerAdd r));
if (SentBytes = SOCKET_ERROR)
then begin
LogEdit.Lines.Add('Send failed');
LogEdit.Lines.Add(IntToStr(WSAGetLastError));
CloseSocket(sClient);
Break;
end;
LogEdit.Lines.Add('File send started');
LogEdit.Lines.Add(inttostr(SentBytes));
total:= total + SentBytes;
end; //end while
на стороне клиента выдает
socket failed с номером 6
так и не догоняю где ошибка
прошу помочь
Сергей М. (2009-04-27 08:23:00) [5]
> клиент корректен или нет?
При использовании UDP за вызовом connect() обычно следуют send()/recv(), иначе connect() лишен смысла.
sendto()/recvfrom() же обычно используются если перед ними не было вызова connect()
> UDP через sendto посылает одну датаграмму
Да.
> пошлет файл целиком одним разом или нет
Смотря какого размера файл.
Кр.того, UDP не гарантирует доставку, так что отправленная дейтаграмма может и не дойти до адресата.
> то что сервер принимает данные или нет я могу узнать через
> Select?
Можешь, на то и select().
> как можно избежать зависания серверной части?
Либо задействовать неблок.режим либо вынести трасп.логику в доп.тред.
foccer (2009-04-26 21:59:00) [6]после прочтения еще нескольких примеров и документаций получилось вот что
клиент:
procedure TForm1.ConnectBtnClick(Sender: TObject);
begin
// connect to the server
sClient:=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
with ServerAddr do begin
sin_family:=AF_INET;
sin_addr.S_addr:=inet_addr(Pchar(AddrEdit.Text));
sin_port:=htons(775);
end;
with LocalAddr do begin
sin_family:=AF_INET;
sin_addr.S_addr:=inet_addr(Pchar(LocalAddrEdit.Text));
sin_port:=htons(775);
end;
if connect(sClient,ServerAddr,sizeof(ServerAddr)) = 0
then begin
LogEdit.Lines.Add('Server connected');
status:=true;
end
else begin
LogEdit.Lines.Add('Connection failed');
LogEdit.Lines.Add(inttostr(WSAGetLastError));
CloseSocket(sClient);
status:=false;
end;
end;
в данном случае с помощью UDP можно коннектиться,т.е. имитирует.
procedure TForm1.SendFileBtnClick(Sender: TObject);
begin
// Send file to the server
if status = true
then begin
SentBytes:=sendto(sClient,sFile.memory^,sFile.Size,0,ServerAddr,sizeof(ServerAdd r));
if (SentBytes = SOCKET_ERROR)
then begin
LogEdit.Lines.Add('Send failed');
LogEdit.Lines.Add(IntToStr(WSAGetLastError));
CloseSocket(sClient);
end
else begin
LogEdit.Lines.Add('File send started');
LogEdit.Lines.Add(inttostr(SentBytes));
end
end
else begin
LogEdit.Lines.Add('The server not connected');
LogEdit.Lines.Add(inttostr(WSAGetLastError));
CloseSocket(sClient);
end;
end;
хотелось б узнать клиент корректен или нет? прочитал что UDP через sendto посылает одну датаграмму, т.е. он пошлет файл целиком одним разом или нет?
если то получается sendto мне надо закинуть в цикл?
а то что сервер принимает данные или нет я могу узнать через Select?
и как можно избежать зависания серверной части?
Сергей М. (2009-04-26 21:18:00) [7]
> прочитал
> что listen используется для Sock_Stream
Именно.
И accept() тоже.
Вместо этих вызовов нужен recv или recvfrom
FireMan_Alexey (2009-04-25 23:37:00) [8]http://Book.itep.ruГлава 7.1 по моему)
Foccer (2009-04-25 20:52:00) [9]и вот что еще прочитал
что listen используется для Sock_Stream
не отрицаю кое что содрал кое что сам....
тогда как быть все таки?
Foccer (2009-04-25 20:45:00) [10]и как мне быть вообще?
Сергей М. (2009-04-25 19:47:00) [11]
> как можно проверить соединен ли клиент на стороне сервера?
Никак.
UDP вообщене подразумевает соединение.
Код, который ты откуда-то содрал и попытался приспособить к решению своего задания, имеет отношение к TCP, а не к UDP.
Foccer (2009-04-25 16:41:00) [12]подскажите пожалуйста
как можно проверить соединен ли клиент на стороне сервера?
Foccer (2009-04-25 12:24:00) [13]ошибся надо еще писать процедуру сохранения(приема) данных
а вот на счет потоков вопрос остался.
Foccer (2009-04-25 12:21:00) [14]спасибо сработало правда я не понял куда он его сохраняет.
у меня есть еще один вопрос
нужно ли мне использовать потоки?
easy (2009-04-25 12:13:00) [15]sFile:=TFileStream.Create
Foccer (2009-04-25 12:12:00) [16]в FileEdit.text передается путь к файлу
Foccer (2009-04-25 12:11:00) [17]
> easy © (25.04.09 12:07) [1]
>
> sFile.Create(FileEdit.Text,fmOpenRead);
а что в нем не так?
easy (2009-04-25 12:07:00) [18]sFile.Create(FileEdit.Text,fmOpenRead);