Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 2011.06.19;
Скачать: [xml.tar.bz2];

Вниз

Отправка очереди из изображений по сети   Найти похожие ветки 

 
WeTeR   (2008-12-28 13:49) [0]

Такая вот проблема отправляю размер фиксированой длины потока , затем поток с изображением. Все нормально приходит и работает, отправляю второй раз - размер просто неотправляется, проверял снифером.

{
Создаем сокет и устанавливаем соеденение
между клиентом и сервером
}

--------------------------Отправка размера
for i:=1 to 5 do
begin
buffs:=inttostr(size)[i];
if (Send(AcceptedSock,buffs,Len,0)=Socket_error) then begin Showmessage("Ошибка сокета"); break; end ;
end;

------------------------Отправка изображения

procedure TForm1.OtpravkaIso(Sender: TObject);
var
  i:integer;
  Buff:array[0..200230] of byte;
h:integer;{для проверки}
Jpeg2:TJpegImage;    {для проверки}
imgWindow:TJpegImage;   {для проверки}
stroka:string;
p:pointer;   {Работает и без этого}
begin
opr:=0;
Bitmap:=TBitmap.Create;
Jpeg:=TJpegImage.Create;
imgWindow:=TJpegImage.Create;
Screenstream.Position:=0;
   while ScreenStream.Position<ScreenStream.Size do    {Начинаем цикл отправки}
    begin

    size:=ScreenStream.Read(Buff,SizeOf(Buff)); {buf имеет тип  Buf:array[0..1023] of byte;}
    Send(AcceptedSock,buff,SizeOf(Buff),0);
    end;
{Проверка как передалось в поток изображение}
ScreenStream.Position:=0;
imgWindow.LoadFromStream(ScreenStream);
  imgWindow.SaveToFile("image\fff.jpg");

  Screenstream.Position:=size;

end;

------------------------{Принимаем размер}

for i:=1 to 5 do
begin                
if (Recv(S,bufr,len ,0)=Socket_error) then begin ShowMessage("Ошибка сокета"); break; end;
s1:=s1+bufr;
end;
label5.Caption:=label5.Caption+" "+s1;
result:=strtoint(s1);

-------------------------Принимаем изображение
procedure Tform1.PoluchISO(Sender: TObject);
var
   Buff2:array[0..200230] of byte;   {Локальный буфер для принятия изображения}
   Bitmap:TBitmap;
 Jpeg:TJpegImage;
 bufrl:Char;{Локальный буфер приема символов}
i,h:Longint;
ScreenStrea:TMemorystream;   {Поток}
size,toread:integer;
Jpeg2:TJpegImage;
ImgSize2:TPoint;  {Тип TPoint это тип записи, содержащий целочисленные значения X и Y.}
imgWindow:TJpegImage;  {Для сохранения файла}
p:Pointer;
begin

ScreenStrea:=TmemoryStream.Create;  {Создаем поток для передачи туда буфера}

ScreenStrea.Size:=rasmer;
ScreenStrea.Position:=0;        {Считываем изображение в поток}
ToRead:=ScreenStrea.Size-ScreenStrea.Position;
min(ToRead,Length(buff2),ToRead);
while (ToRead>0) do
begin
Recv(S,buff2,Sizeof(buff2) ,0);
ScreenStrea.Write(Buff2,ToRead);
ToRead:=ScreenStrea.Size-ScreenStrea.Position;
min(ToRead,Length(buff2),ToRead);
end;

ScreenStrea.Position:=0;

 imgWindow:=TJpegImage.Create;
ScreenStrea.Position:=0;
imgWindow.LoadFromStream(ScreenStrea);

  imgWindow.SaveToFile("image\fff1.jpg");
  Ekran.Show;
Ekran.image1.Picture.LoadFromFile("image\fff1.jpg");

end;


 
WeTeR   (2008-12-28 13:55) [1]

причем если я отправляю размер потом получаю его без отправки изображения то это сколько угодно , стоит только один раз отправить и получить изображение , и больше неполучится. Я только могу предположить что остаются какие то даные которые мешают нормальной последующей отправке.


 
Palladin ©   (2008-12-28 15:06) [2]


> for i:=1 to 5 do
> begin
> buffs:=inttostr(size)[i];
> if (Send(AcceptedSock,buffs,Len,0)=Socket_error) then begin Showmessage("Ошибка сокета"); break; end ;
end;


я так понимаю, ты железно уверен, что размер изображения - 5ти значное число?

что за len, что за buffs, что за бредовая идея 5 раз переводить строчку в число?


> for i:=1 to 5 do
> begin                
> if (Recv(S,bufr,len ,0)=Socket_error) then begin ShowMessage("Ошибка сокета"); break; end;
> s1:=s1+bufr;
> end;
> label5.Caption:=label5.Caption+" "+s1;
> result:=strtoint(s1);


И сколько len к тебе приходит, не ужто по одному?

Никто и никогда тебе не пообещает, что если отправлено 5 раз по 1 байту, придет 5 раз по 1 байту, а не за один раз 5.


 
DVM ©   (2008-12-28 17:55) [3]


> WeTeR   (28.12.08 13:49)  

Может тебе лучше HTTP использовать? И компоненты соответствующие TIdHTTP и TIdHTTPServer? Там тебе проще будет.


 
Сергей М. ©   (2008-12-28 18:19) [4]


> WeTeR


Send - это функция, понимаешь ? Функция !
И Recv - это тоже функция.


 
Slym ©   (2008-12-28 19:45) [5]

фтарой раз за день ссылку даю
http://delphimaster.net/view/6-1227604925/


 
WeTeR   (2008-12-29 06:33) [6]

->Никто и никогда тебе не пообещает, что если отправлено 5 раз по 1 байту, придет 5 раз по 1 байту, а не за один раз 5.

Да размер фиксированый пятизначное число и количество знаков неизменяется, переводится в строку и отправляется по одному символу
buffs имеет тип Char
И считывается на клиенте оно тоже по одному символу, может и можно сделать оптимальней но суть проблемы точно не в этом

-> Send - это функция, понимаешь ? Функция !
И Recv - это тоже функция

Так подскажи какой из этого должен быть вывод ? Ведь функций много и все они используются по разному.


 
Сергей М. ©   (2008-12-29 08:19) [7]


> какой из этого должен быть вывод ?


Если это функции, то и использовать их нужно как функции, а не как процедуры.


> функций много и все они используются по разному


Но всех их объединяет одно - все они, в отличие от процедур, возвращают результат. А ты этот результат напрочь игнорируешь, благо Паскаль позволяет это.
Какие результаты и что означает каждый из них - это описано в справке и ресурсах msdn для каждой функции.


 
WeTeR   (2008-12-29 08:42) [8]

--> А ты этот результат напрочь игнорируешь, благо Паскаль позволяет это.

Я тебя понял ,но скажи что я здесь проигнорировал или как здесь сделать лучше так чтоб это решило проблему, если она в этом.

Recv(S,bufr,len ,0)
S -Сокет
bufr - то что мы отправляем (указатель на масив даных)
len  - длина того что мы отправляем.
0 - здесь можно поставить ключь режим чтения без уничтожения даных в буфере или с уничтожением

Send(S,bufr,len ,0)

S -Сокет
bufr - то что мы отправляем (указатель на масив даных)
len  - длина того что мы отправляем.
0 - здесь можно поставить ключь режим чтения без уничтожения даных в буфере или с уничтожением


 
Palladin ©   (2008-12-29 08:48) [9]


> Я тебя понял ,но скажи что я здесь проигнорировал

Как что, результат функции. Ты вообще в курсе чем процедура от функции отличается?


 
WeTeR   (2008-12-29 09:13) [10]


> Как что, результат функции. Ты вообще в курсе чем процедура
> от функции отличается?


Мля нетоми скажи конкретней , я между прочим только учусь и поэтому могу незнать всех подробностей, какой имено результат я должен получить от Send и Recv


 
Сергей М. ©   (2008-12-29 09:19) [11]


> что я здесь проигнорировал


Ты проигнорировал результат !

РезультатВыполненияФункцииSend := Send(...параметры вызова функции ..);

РезультатВыполненияФункцииRecv := Recv(...параметры вызова функции ..);


> я между прочим только учусь


Млякать ты уже, я смотрю, научился, а читать справку когда будешь учиться ?


> какой имено результат я должен получить от Send


Открываем справку к ф-ции, читаем:

Return Values

If no error occurs, send returns the total number of bytes sent. (Note that this can be less than the number indicated by len.) Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED A successful WSAStartup must occur before using this function.
WSAENETDOWN The network subsystem has failed.
WSAEACCES The requested address is a broadcast address, but the appropriate flag was not set.
WSAEINTR The (blocking) call was canceled through WSACancelBlockingCall.
WSAEINPROGRESS A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
WSAEFAULT The buf argument is not totally contained in a valid part of the user address space.
WSAENETRESET The connection has been broken due to the remote host resetting.
WSAENOBUFS No buffer space is available.
WSAENOTCONN The socket is not connected.
WSAENOTSOCK The descriptor is not a socket.
WSAEOPNOTSUPP MSG_OOB was specified, but the socket is not stream style such as type SOCK_STREAM, out-of-band data is not supported in the communication domain associated with this socket, or the socket is unidirectional and supports only receive operations.
WSAESHUTDOWN The socket has been shut down; it is not possible to send on a socket after shutdown has been invoked with how set to SD_SEND or SD_BOTH.
WSAEWOULDBLOCK The socket is marked as nonblocking and the requested operation would block.
WSAEMSGSIZE The socket is message oriented, and the message is larger than the maximum supported by the underlying transport.
WSAEHOSTUNREACH The remote host cannot be reached from this host at this time.
WSAEINVAL The socket has not been bound with bind, or an unknown flag was specified, or MSG_OOB was specified for a socket with SO_OOBINLINE enabled.
WSAECONNABORTED The virtual circuit was terminated due to a time-out or other failure. The application should close the socket as it is no longer usable.
WSAECONNRESET The virtual circuit was reset by the remote side executing a "hard" or "abortive" close. For UPD sockets, the remote host was unable to deliver a previously sent UDP datagram and responded with a "Port Unreachable" ICMP packet. The application should close the socket as it is no longer usable.
WSAETIMEDOUT The connection has been dropped, because of a network failure or because the system on the other end went down without notice.


 
Slym ©   (2008-12-29 11:08) [12]

WeTeR   (29.12.08 9:13) [10]
returns the total number of bytes sent/recv
это не равно "длина того что мы отправляем/принимаем"!
это как обойма автомата... болше N патронов не ляжет... должен подождать, "дозаправить", и дальше строчить


 
FireMan_Alexey   (2009-02-04 02:06) [13]

сделай так:

Var
 Size:Integer;
 RecvSize:Integer;
...
 Size:=SizeOf(Buffer);
 //  Это не обязательно, но тоже ничего :)
 //===============================
 IOCTLSocket(Socket,FIONREAD,RecvSize);
 If Size>RecvSize Then Size:=RecvSize;
 //===============================
 Size:=Recv(socket,Buffer,Size,0);
 If Size=SOCKET_ERROR Then
   Begin
      Error:=WSAGetLastError;
      //Проверь на WSAEWOULDBLOCK
      ....
      //Format C: /q  :)
   End;
 If Size=0 Then CloseSocket(Socket);
 Stream.Write(Buffer,Size);
//============================================

Аналогично с Send
MaxSend:=4096;  
While true do
Begin
   Size:=SizeOf(Buffer);
 If Size>MaxSend Then Size:=MaxSend;
 //===============================
 Size:=Send(socket,Buffer,Size,0);
 If Size=SOCKET_ERROR Then
   Begin
      Error:=WSAGetLastError;
      //Проверь на WSAEWOULDBLOCK - то надо подождать!!!!
      //пока буфер отправки не освободиться!!!
      ....
      //Format C: /q  :)
   End;
  ...
  //ну и следи чтоб буфер правильно наполнялся
End;
//============================================


 
FireMan_Alexey   (2009-02-04 02:11) [14]

Да при WSAEWOULDBLOCK надо из цикла выйти, а то я забыл, ну или при опустошении буфера передачи(в смыле твоего буфера)


 
FireMan_Alexey   (2009-02-04 02:31) [15]

А вообще немешало бы использовать Select для того, чтобы знать можно что-то посылать или принимать!
Да и размер максимального кадра у TCP - 8192, а посылать нужно не больше 4096.

И я бы посылал пакет заместо строкового размера в 5 байт, а если разрешение 1600х1200 ?

Type
  MyScreen=Packed record
     ID:Word; // signature
     Size:Integer; //Максимальній размер 2 Гб-1, а если Cardinal 4Гб-1 :)
     ....
  End;


 
FireMan_Alexey   (2009-02-04 02:42) [16]

Если что не так написал не судите строго :)


 
FireMan_Alexey   (2009-02-04 03:00) [17]

Можеш посмотреть исходники SCKTCOMP.PAS ->[DELPHI]\SOURCE\VCL\
Там есть SendStream или Send(S:TStream) не помню :)
А вообще Digitman раньше отсылал на http://Book.Itep.Ru там есть раздел Winsock или Сокеты Беркли, там можно кое-что почитать :)


 
имя   (2009-03-30 11:37) [18]

Удалено модератором


 
имя   (2009-03-30 11:37) [19]

Удалено модератором



Страницы: 1 вся ветка

Форум: "Сети";
Текущий архив: 2011.06.19;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.51 MB
Время: 0.004 c
15-1298655944
Fergo
2011-02-25 20:45
2011.06.19
Интересный алгоритм в обычном калькуляторе.


2-1296316880
Пироги
2011-01-29 19:01
2011.06.19
Помогите настроить отображение массива в TListView?


2-1299768007
harisma
2011-03-10 17:40
2011.06.19
Слияние двух стринглистов


2-1299788475
rodionov_uv
2011-03-10 23:21
2011.06.19
помогите организовать проверку


2-1300183147
Avil
2011-03-15 12:59
2011.06.19
Mysql stored proc, записи в цикле





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский