Конференция "Сети" » проблемы с Winsock [D7, WinXP]
 
  • Foccer (25.04.09 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 © (25.04.09 12:07) [1]
    sFile.Create(FileEdit.Text,fmOpenRead);
  • Foccer (25.04.09 12:11) [2]

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

    а что в нем не так?
  • Foccer (25.04.09 12:12) [3]
    в FileEdit.text передается путь к файлу
  • easy © (25.04.09 12:13) [4]
    sFile:=TFileStream.Create
  • Foccer (25.04.09 12:21) [5]
    спасибо сработало правда я не понял куда он его сохраняет.
    у меня есть еще один вопрос
    нужно ли мне использовать потоки?
  • Foccer (25.04.09 12:24) [6]
    ошибся надо еще писать процедуру сохранения(приема) данных
    а вот на счет потоков вопрос остался.
  • Foccer (25.04.09 16:41) [7]
    подскажите пожалуйста
    как можно проверить соединен ли клиент на стороне сервера?
  • Сергей М. © (25.04.09 19:47) [8]

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


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

    Код, который ты откуда-то содрал и попытался приспособить к решению своего задания, имеет отношение к TCP, а не к UDP.
  • Foccer (25.04.09 20:45) [9]
    и как мне быть вообще?
  • Foccer (25.04.09 20:52) [10]
    и вот что еще прочитал
    что listen используется для Sock_Stream
    не отрицаю кое что содрал кое что сам....
    тогда как быть все таки?
  • FireMan_Alexey © (25.04.09 23:37) [11]
    http://Book.itep.ru Глава 7.1 по моему)
  • Сергей М. © (26.04.09 21:18) [12]

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


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

    Вместо этих вызовов нужен recv или recvfrom
  • foccer (26.04.09 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?
    и как можно избежать зависания серверной части?
  • Сергей М. © (27.04.09 08:23) [14]

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


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


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


    Да.


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


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


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


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


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


    Либо задействовать неблок.режим либо вынести трасп.логику в доп.тред.
  • foccer (28.04.09 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
    так и не догоняю где ошибка
    прошу помочь
  • Сергей М. © (28.04.09 19:23) [16]
    Отладчик в зубы  - и вперед !


    > не догоняю


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

    Готов ?

    $500 - и получишь готовое.
  • foccer (28.04.09 19:41) [17]
    ^_^
  • Сергей М. © (28.04.09 19:58) [18]
    Лыбу строй преподу)
 
Конференция "Сети" » проблемы с Winsock [D7, WinXP]
Есть новые Нет новых   [134435   +33][b:0][p:0.001]