Форум: "Сети";
Текущий архив: 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.003 c