Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Размер буфера в sendTo, recvfrom. [D7, WinXP]


lockheed_man ©   (2005-11-16 22:09:00) 

Проблема в определении буфера для исходящего и входящего сообщений. Например, если написать
recvfrom(vServerSocket, MsgBuff, 65535, 0, FromAddr, FromAddrSize), где MsgBuff: String, то при входящем сообщении "123" WSAAsincSelect-событие происходит дважды и по завершинии процедуры обработки получения сообщения приложение просто вылетает, а из делфи появляется окно с ассемблером и куча всякого "Access violation to address...". А если написать
recvfrom(vServerSocket, MsgBuff, SizeOf(MsgBuff), 0, FromAddr, FromAddrSize), то выдает ошибку что буфер слишком мал для принятия сообщения и оно урезано. Результат - ничего не приходит.
Вот обработчик события при наличии в буфере сокета датаграмы:
procedure TMainForm.WMSocketEvent(var msg: TMessage);
var
 MsgBuff: String;
 RecievedMsg: String;
 FromAddr: TSockAddr;
 FromAddrSize: Integer;
 MsgSender: String;
begin
 if WSAGetSelectError(msg.LParam) <> 0 then
   begin
     MessageDlg('Error recieving data', mtInformation, [mbOK], 0);
     Exit;
   end;
 case WSAGetSelectEvent(msg.LParam) of
   FD_READ:
     begin
       FromAddrSize := SizeOf(FromAddr);
       MsgBuff := '';
       if recvfrom(vServerSocket, MsgBuff, 65535, 0, FromAddr, FromAddrSize) = SOCKET_ERROR then
         begin
           SocketErrorMsg := GetRecvFromError(WSAGetLastError);
           MessageDlg('Recieving error' + #13 + SocketErrorMsg,mtWarning,[mbOK],0);
           Exit;
         end;
       RecievedMsg := RecievedMsg + MsgBuff;
       MsgSender := IntToStr(ntohl(FromAddr.sin_addr.S_addr));
     end;
 end;
 //if
//ShowRecievedMsg(RecievedMsg,MsgSender,'',DateTimeToStr(Now));
end;

Если есть какие советы, то поделитесь опытом. Заранее Спасибо


lockheed_man   (2005-11-17 19:52:00) [1]

Все, спасибо всем за советы. Вроде разобрался.


lockheed_man   (2005-11-17 19:33:00) [2]

>И самое главное! Брать из MsgBuf столько байт, сколько пришло ;)))
Можно про этот момент поподробнее. Просто я в сокетах ну совсем новичек. Заранее благодарен.


XProger   (2005-11-17 18:50:00) [3]

И самое главное! Брать из MsgBuf столько байт, сколько пришло ;)))


Digitman   (2005-11-17 08:39:00) [4]


> lockheed_man ©   (17.11.05 05:52) [4]


отправляешь-то поди тоже MsgBuf: string?

если так, то у тебя там та же самая ошибка - при передаче в кач-ве буфера следует указывать не MsgBuf, а PChar(MsgBuf)^ либо MsgBuf[1]


lockheed_man   (2005-11-17 05:52:00) [5]

Ок. Спасибо за разъяснение. Может я все-таки не все до конца понял, но дело в том если писать так как Вы мне посоветовали то вместо отправленного сообщения я получаю какую-то несуразицу, состоящую всего из трех символов. Может поясните поподробнее как все же правильно использовать эти функции или подскажете ресурс на котором было бы для начинающих описаны методы работы с WinSock.


Германн   (2005-11-17 02:21:00) [6]


> lockheed_man ©   (16.11.05 23:27) [2]
> Спасибо. Приду домой обязательно проверю. Но можна еще один
> ламерский вопросик? Почему MsgBuff[1]?

Функция хочет получить во втором параметре адрес ячейки первого байта того буфера, куда она должна загрузить некие данные. А MsgBuff в данном случае передает в функцию адрес первого байта переменной, которая хранит вышеописанный адрес, в отличие от MsgBuff[1], который как раз и является тем, что нужно функции.

Был бы я..., сказал бы о).  :)


lockheed_man   (2005-11-16 23:27:00) [7]

Спасибо. Приду домой обязательно проверю. Но можна еще один ламерский вопросик? Почему MsgBuff[1]?


XProger   (2005-11-16 22:47:00) [8]

Неудивительно!

MsgBuff: String;
...
MsgBuff := '';
recvfrom(..., MsgBuff, 65535, ...)


А вот так должно заработать:

MsgBuff: String;
...
SetLength(MsgBuff, 65535);
recvfrom(..., MsgBuff[1], 65535, ...)


Учи Delphi!


Наверх

Титульная страница Поиск, карта сайта Написать письмо