-
Здравствуйте уважаемые. Я студент. Нам дали задание сделать пару проектов с помощью этой либы(если не ошибаюсь) одна из задач передача файла посредством протокола 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. дальше нуль эмоций. Прошу подсказать что я пропустил.
-
sFile.Create(FileEdit.Text,fmOpenRead);
-
> easy © (25.04.09 12:07) [1] > > sFile.Create(FileEdit.Text,fmOpenRead);
а что в нем не так?
-
в FileEdit.text передается путь к файлу
-
sFile:=TFileStream.Create
-
спасибо сработало правда я не понял куда он его сохраняет. у меня есть еще один вопрос нужно ли мне использовать потоки?
-
ошибся надо еще писать процедуру сохранения(приема) данных а вот на счет потоков вопрос остался.
-
подскажите пожалуйста как можно проверить соединен ли клиент на стороне сервера?
-
> как можно проверить соединен ли клиент на стороне сервера?
Никак. UDP вообще не подразумевает соединение.
Код, который ты откуда-то содрал и попытался приспособить к решению своего задания, имеет отношение к TCP, а не к UDP.
-
и как мне быть вообще?
-
и вот что еще прочитал что listen используется для Sock_Stream не отрицаю кое что содрал кое что сам.... тогда как быть все таки?
-
-
> прочитал > что listen используется для Sock_Stream
Именно. И accept() тоже.
Вместо этих вызовов нужен recv или recvfrom
-
после прочтения еще нескольких примеров и документаций получилось вот что клиент: 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? и как можно избежать зависания серверной части?
-
> клиент корректен или нет?
При использовании UDP за вызовом connect() обычно следуют send()/recv(), иначе connect() лишен смысла. sendto()/recvfrom() же обычно используются если перед ними не было вызова connect()
> UDP через sendto посылает одну датаграмму
Да.
> пошлет файл целиком одним разом или нет
Смотря какого размера файл. Кр.того, UDP не гарантирует доставку, так что отправленная дейтаграмма может и не дойти до адресата.
> то что сервер принимает данные или нет я могу узнать через > Select?
Можешь, на то и select().
> как можно избежать зависания серверной части?
Либо задействовать неблок.режим либо вынести трасп.логику в доп.тред.
-
сервер без неблок режим и селекта 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 так и не догоняю где ошибка прошу помочь
-
Отладчик в зубы - и вперед !
> не догоняю
За "догон" платить следует.
Готов ?
$500 - и получишь готовое.
-
^_^
-
Лыбу строй преподу)
|