Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Сети > Опять проблемы с RECV


Автор: XSInet 2.5.2006, 15:36
Есть буфер на 10 байт
recv(Sock, buffer, sizeof(buffer), 0)

Так вот, если пришлют 11 байт (>10), то recv вызовется 2 раза. Как этого избежать ? 

Автор: Snowy 2.5.2006, 15:39
Перед получением данных из сокета, проверь кол-во байт в буфере.
Если меньше ожидаемого, то не читай или читай столько, сколько есть.
Проверить кол-во байт в буфере можно так:
Код

  ByteKol := Socket.ReceiveBuf(pointer(nil)^,-1);
 

Автор: XSInet 2.5.2006, 16:03
Я на API пишу. 

Автор: Snowy 2.5.2006, 16:32
Ну тогда так:
Код

var
  BytesKol: integer;
begin
  ioctlsocket(Sock, FIONREAD, Longint(BytesKol);
  if BytesKol >= 10 then ...
  else ....
   

Автор: XSInet 2.5.2006, 18:03
Всё равно второй раз процедуру вызывает. Или я что-то не понял ? 

Автор: Snowy 2.5.2006, 18:25
ioctlsocket это функция wsock32.dll
Она записывает в переменную BytesKol кол-во байт в буфере сокета.
Sock - это твой сокет, который ты используешь в recv(Sock, buffer, sizeof(buffer), 0)
Что тут непонятно? 

Автор: Rouse_ 3.5.2006, 08:32
Код

var
  BytesKol: integer;
  buffer: array of Byte;
begin
  ioctlsocket(Sock, FIONREAD, Longint(BytesKol);
  SetLength(buffer, BytesKol);
  // теперь получай


Добавлено @ 08:35 
Эээ... 
Код

ioctlsocket(Sock, FIONREAD, Longint(@BytesKol));
 

Автор: XSInet 4.5.2006, 18:05
По чему то не работает этот код:

Фругмент:
Код

case FD_ACCEPT:
    Client_Socket = accept(Accepting_Socket, NULL, NULL);
    MessageBoxA(hwnd, "Client connected", NULL, 0);
        char LOL[10];
        recv(Client_Socket, LOL, 10, 0);
    WSAAsyncSelect(Client_Socket, hwnd, WM_USER+1, FD_READ | FD_WRITE | FD_CLOSE);
    break;


Извиняюсь что на С++.
Так вот функция RECV просто "пролистывается", т.е. не выполняется. На ней программа не останавливается, хотя Client_Socket - блокирующий сокет  

Автор: Rouse_ 5.5.2006, 00:30
Еще бы...
Тут нарушена вся логика. Какой RECV может быть на входящем ACCEPT? Даже на асинхронке для этого отдельный калбэк висит.
WSAAsyncSelect должен быть вызван ДО этого события (что собственно у тебя по всей видимости и сделано)

recv должен быть вызван на событии чтения, а именно FD_READ

Добавлено @ 00:35 
Цитата(XSInet @  4.5.2006,  19:05 Найти цитируемый пост)
хотя Client_Socket - блокирующий сокет  

ЗЗЫ: Это не может быть блокирующим сокетом. Научись отличать три модели транспорта. Блокирующий, неблокирующий и асинхронный.
Вникай до полного просветления: http://book.itep.ru/ 

Автор: XSInet 8.5.2006, 04:46
Цитата

ЗЗЫ: Это не может быть блокирующим сокетом

А какой же он тогда ? На recv Он как раз блокирующий. Вот после WSAAsyncSelect(Client_Socket, ...) он становится асинхронным. 

Автор: Rouse_ 10.5.2006, 09:16
Цитата(XSInet @  8.5.2006,  05:46 Найти цитируемый пост)
На recv Он как раз блокирующий. 

Если приходит FD_ACCEPT значит он уже не блокирующий. Ты информацию по моей ссылке изучил? 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)