Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 2011.08.28;
Скачать: [xml.tar.bz2];

Вниз

проблемы с 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.009 c
15-1304851360
Palladin
2011-05-08 14:42
2011.08.28
Куда девать нечитабельные и старые CD/DVD ?


15-1304354356
@!!ex
2011-05-02 20:39
2011.08.28
Как влияет Range check на работу результирующего кода?


15-1304713794
Юрий
2011-05-07 00:29
2011.08.28
С днем рождения ! 7 мая 2011 суббота


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


15-1305086552
Demo
2011-05-11 08:02
2011.08.28
Дисковое пространство для форума





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский