![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Размер буфера в 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!