Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2011.08.28;
Скачать: CL | DM;

Вниз

проблемы с Winsock   Найти похожие ветки 

 
Foccer   (2009-04-25 11:54) [0]

Здравствуйте уважаемые.
Я студент. Нам дали задание сделать пару проектов с помощью этой либы(если не ошибаюсь)
одна из задач передача файла посредством протокола 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. дальше нуль эмоций.
Прошу подсказать что я пропустил.


 
easy ©   (2009-04-25 12:07) [1]

sFile.Create(FileEdit.Text,fmOpenRead);


 
Foccer   (2009-04-25 12:11) [2]


> easy ©   (25.04.09 12:07) [1]
>
> sFile.Create(FileEdit.Text,fmOpenRead);

а что в нем не так?


 
Foccer   (2009-04-25 12:12) [3]

в FileEdit.text передается путь к файлу


 
easy ©   (2009-04-25 12:13) [4]

sFile:=TFileStream.Create


 
Foccer   (2009-04-25 12:21) [5]

спасибо сработало правда я не понял куда он его сохраняет.
у меня есть еще один вопрос
нужно ли мне использовать потоки?


 
Foccer   (2009-04-25 12:24) [6]

ошибся надо еще писать процедуру сохранения(приема) данных
а вот на счет потоков вопрос остался.


 
Foccer   (2009-04-25 16:41) [7]

подскажите пожалуйста
как можно проверить соединен ли клиент на стороне сервера?


 
Сергей М. ©   (2009-04-25 19:47) [8]


> как можно проверить соединен ли клиент на стороне сервера?


Никак.
UDP вообще не подразумевает соединение.

Код, который ты откуда-то содрал и попытался приспособить к решению своего задания, имеет отношение к TCP, а не к UDP.


 
Foccer   (2009-04-25 20:45) [9]

и как мне быть вообще?


 
Foccer   (2009-04-25 20:52) [10]

и вот что еще прочитал
что listen используется для Sock_Stream
не отрицаю кое что содрал кое что сам....
тогда как быть все таки?


 
FireMan_Alexey ©   (2009-04-25 23:37) [11]

http://Book.itep.ru Глава 7.1 по моему)


 
Сергей М. ©   (2009-04-26 21:18) [12]


> прочитал
> что listen используется для Sock_Stream


Именно.
И accept() тоже.

Вместо этих вызовов нужен recv или recvfrom


 
foccer   (2009-04-26 21:59) [13]

после прочтения еще нескольких примеров и документаций получилось вот что
клиент:
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-27 08:23) [14]


> клиент корректен или нет?


При использовании UDP за вызовом connect() обычно следуют send()/recv(), иначе connect() лишен смысла.
sendto()/recvfrom() же обычно используются если перед ними не было вызова connect()


> UDP через sendto посылает одну датаграмму


Да.


> пошлет файл целиком одним разом или нет


Смотря какого размера файл.
Кр.того, UDP не гарантирует доставку, так что отправленная дейтаграмма может и не дойти до адресата.


> то что сервер принимает данные или нет я могу узнать через
> Select?


Можешь, на то и select().


> как можно избежать зависания серверной части?


Либо задействовать неблок.режим либо вынести трасп.логику в доп.тред.


 
foccer   (2009-04-28 18:27) [15]

сервер без неблок режим и селекта
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-28 19:23) [16]

Отладчик в зубы  - и вперед !


> не догоняю


За "догон" платить следует.

Готов ?

$500 - и получишь готовое.


 
foccer   (2009-04-28 19:41) [17]

^_^


 
Сергей М. ©   (2009-04-28 19:58) [18]

Лыбу строй преподу)



Страницы: 1 вся ветка

Текущий архив: 2011.08.28;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.008 c
15-1303914069
xayam
2011-04-27 18:21
2011.08.28
Идея для программы


9-1189535717
LbS!
2007-09-11 22:35
2011.08.28
Подскажите тему :)


2-1305274898
Panky
2011-05-13 12:21
2011.08.28
перемешение по таблице


2-1305286843
Gu
2011-05-13 15:40
2011.08.28
Вопрос по классам


3-1262553825
wipr
2010-01-04 00:23
2011.08.28
отмена удаления в таблицах DBF