Модераторы: Snowy, Poseidon, MetalFan

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Сокеты, Соединение TCP/IP 
:(
    Опции темы
WERITAS
Дата 29.4.2007, 12:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


********
**


Профиль
Группа: Участник
Сообщений: 582
Регистрация: 2.5.2005
Где: Москва

Репутация: нет
Всего: 5



Сразу скажу, что ни разу не пользовался компонентами Delphi для работы в  сети. Где здесь у меня ошибка:

Для сервера:
Код

procedure TForm1.BitBtn1Click(Sender: TObject);
begin
  TcpServer1.LocalHost:= '127.0.0.1';
  TcpServer1.LocalPort:= '1121';
  TcpServer1.Active:= true;

end;
procedure TForm1.TcpServer1Accept(Sender: TObject; ClientSocket: TCustomIpClient);
begin
  ShowMessage('Hello!');
end;


Для клиента:
Код

procedure TForm1.Button1Click(Sender: TObject);
begin
  TcpClient1.RemoteHost:= '127.0.0.1';
  TcpClient1.RemotePort:= '1121';
  TcpClient1.Active:= true;

  if TcpClient1.Connect then ShowMessage('Connect!');
end;

Не прилетает ни одно из сообщений :(


--------------------
Арт-менеджер клуба, разрешивший концерт Алексея Глызина, уволен с формулировкой "Мудак"
PM MAIL   Вверх
Exai1e
Дата 29.4.2007, 13:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 908
Регистрация: 3.12.2006
Где: Moscow

Репутация: нет
Всего: 30



Сервер
Код

unit UServerMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ScktComp;

type
  TForm1 = class(TForm)
    ServerSocket1: TServerSocket;
    Button1: TButton;
    ListBox1: TListBox;
    procedure ServerSocket1ClientRead(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  ServerSocket1.Active := false;
  ServerSocket1.Close;
  Close;  
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  ServerSocket1.Port   := 777;
  ServerSocket1.Active := true;
end;

procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
var
  s : string;
  i : integer;
begin
    s := TimeToStr(now) + ' ' + Socket.ReceiveText;
  //s := TimeToStr(now) +  ' ' + '>' + ' ' + Socket.ReceiveText;
  ListBox1.Items.Add(s);
  for I := 0 to ServerSocket1.Socket.ActiveConnections - 1 do
    if ServerSocket1.Socket.Connections[i].SocketHandle <> Socket.SocketHandle then
      ServerSocket1.Socket.Connections[i].SendText(s);
end;

end.


Клиент
Код

unit UClientMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ScktComp, StdCtrls;

type
  TForm1 = class(TForm)
    edSendText: TEdit;
    btnConnect: TButton;
    edAdress: TEdit;
    edPort: TEdit;
    btnSend: TButton;
    ClientSocket1: TClientSocket;
    Label1: TLabel;
    Label2: TLabel;
    edName: TEdit;
    Label3: TLabel;
    Memo1: TMemo;
    procedure ClientSocket1Connecting(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure btnSendClick(Sender: TObject);
    procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
    procedure FormDestroy(Sender: TObject);
    procedure btnConnectClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  Nick : string;

implementation

{$R *.dfm}

{Connect}
procedure TForm1.btnConnectClick(Sender: TObject);
begin
  ClientSocket1.Host    := edAdress.Text;
  ClientSocket1.Port    := StrToInt(edPort.Text);
  Nick := edName.Text;
  if not ClientSocket1.Active then ClientSocket1.Active := true;
  edName.Enabled        := false;
  edAdress.Enabled      := false;
  edport.Enabled        := false;
  btnConnect.Enabled    := false;
end;

{Send message}
procedure TForm1.btnSendClick(Sender: TObject);
begin
  if edSendText.Text <> '' then
    begin
      ClientSocket1.Socket.SendText(Nick + ' ' + ' > ' + ' ' + edSendText.Text);
      Memo1.lines.Add(TimeToStr(now) + ' ' + Nick + ' ' + ' > ' + ' ' +  edSendText.Text);
      edSendText.Text := '';
    end;
end;

procedure TForm1.ClientSocket1Connecting(Sender: TObject;
  Socket: TCustomWinSocket);
begin
  Socket.SendText(Nick + ' Вошел в чат');
end;

procedure TForm1.ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
begin
  Memo1.Lines.Add(Socket.ReceiveText);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  ClientSocket1.Socket.SendText(Nick + ' Покинул чат');
  ClientSocket1.Active := false;
  ClientSocket1.Close;
  Close;
end;

end.


пасмари, пример рабочий, мб поможет...


--------------------
"Решение зависит от выбранного геморроя" © Snowy
"у нас как в армии - либо работает, либо так и задумано"
PM MAIL ICQ   Вверх
WERITAS
Дата 29.4.2007, 13:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


********
**


Профиль
Группа: Участник
Сообщений: 582
Регистрация: 2.5.2005
Где: Москва

Репутация: нет
Всего: 5



Код

    ServerSocket1: TServerSocket;


Код

    ClientSocket1: TClientSocket;


Что это? У меня в Delphi7 такого нет

Это сообщение отредактировал(а) WERITAS - 29.4.2007, 14:10


--------------------
Арт-менеджер клуба, разрешивший концерт Алексея Глызина, уволен с формулировкой "Мудак"
PM MAIL   Вверх
Exai1e
Дата 29.4.2007, 14:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 908
Регистрация: 3.12.2006
Где: Moscow

Репутация: нет
Всего: 30



Эт я сам делал
вот в архиве


--------------------
"Решение зависит от выбранного геморроя" © Snowy
"у нас как в армии - либо работает, либо так и задумано"
PM MAIL ICQ   Вверх
Sanchezzz
Дата 29.4.2007, 22:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1670
Регистрация: 19.11.2006
Где: Voronezh

Репутация: 1
Всего: 60



сокеты лежат отдельно в папке ...Delphi\bin\dclSocket70.bpl


--------------------
Понравился ответ "+" по репе, не забываем закрывать тему, заказы в LS.
PM MAIL Skype GTalk   Вверх
Exai1e
Дата 29.4.2007, 22:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 908
Регистрация: 3.12.2006
Где: Moscow

Репутация: нет
Всего: 30



WERITAS, Надо было сразу уточнить про что ты... а то 
~
Цитата
Что за зверь такой, у меня в Delphi 7 такого нет



--------------------
"Решение зависит от выбранного геморроя" © Snowy
"у нас как в армии - либо работает, либо так и задумано"
PM MAIL ICQ   Вверх
WERITAS
Дата 30.4.2007, 07:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


********
**


Профиль
Группа: Участник
Сообщений: 582
Регистрация: 2.5.2005
Где: Москва

Репутация: нет
Всего: 5



Exai1e 
А я это и цитировал:
Цитата

Код

     ServerSocket1: TServerSocket;


Код

     ClientSocket1: TClientSocket;


Что это? У меня в Delphi7 такого нет




--------------------
Арт-менеджер клуба, разрешивший концерт Алексея Глызина, уволен с формулировкой "Мудак"
PM MAIL   Вверх
Exai1e
Дата 30.4.2007, 10:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 908
Регистрация: 3.12.2006
Где: Moscow

Репутация: нет
Всего: 30



Exai1e, Ну когда я отписывался цитата была другая smile


--------------------
"Решение зависит от выбранного геморроя" © Snowy
"у нас как в армии - либо работает, либо так и задумано"
PM MAIL ICQ   Вверх
WERITAS
Дата 30.4.2007, 11:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


********
**


Профиль
Группа: Участник
Сообщений: 582
Регистрация: 2.5.2005
Где: Москва

Репутация: нет
Всего: 5



Ну надо было выждать всего полминуты  smile  )))

Всё равно спасибо) Я с компонентов TcpClient/TcpServer перешёл к TClientSocket/TServerSocket smile Так что не зря старался ;-)

Это сообщение отредактировал(а) WERITAS - 30.4.2007, 11:23


--------------------
Арт-менеджер клуба, разрешивший концерт Алексея Глызина, уволен с формулировкой "Мудак"
PM MAIL   Вверх
Saygak
  Дата 2.5.2007, 12:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 2.5.2007

Репутация: нет
Всего: 1



Вопрос, собственно, Exai1e: ты приводишь пример чата и все работает, но при изменении Socket.SendText(...) на Socket.SendStream(...) почему-то возникает ошибка.
промер программы:
Код

procedure TMainForm.ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
var
  s: String;
begin
  s := Socket.ReceiveText;
  if s='D' then begin
    BitMap.Canvas.CopyRect(R1, DC, R1);
    Image1.Picture.Bitmap := BitMap;
    Image1.Picture.Graphic.SaveToStream(ms);
    ms.Position := 0;
    Socket.SendStream(ms); //вот тут и возникает ошибка
    ms.Clear;
  end;
end;

 smile 
PM MAIL ICQ   Вверх
Snowy
Дата 2.5.2007, 13:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 53
Всего: 484



А ты попробуй использовать локальные переменные, а не глобальные - всё само пройдёт  smile
Вот где тут ms создаётся? или битмап? и прочие переменные?
И кто их ещё юзает в данный момент?
PM MAIL   Вверх
Saygak
Дата 2.5.2007, 13:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 2.5.2007

Репутация: нет
Всего: 1



Snowy: щас приведу полный код.
Сервер:
Код

unit UServerMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ScktComp, StdCtrls, ComCtrls, ActnList, StdActns, Menus,
  ExtCtrls;

type
  TMainForm = class(TForm)
    ServerSocket1: TServerSocket;
    StatusBar1: TStatusBar;
    Button1: TButton;
    MainMenu1: TMainMenu;
    File1: TMenuItem;
    ActionList1: TActionList;
    FileExit1: TFileExit;
    ServerStart1: TAction;
    ServerStop1: TAction;
    Option1: TMenuItem;
    Preference1: TAction;
    Start1: TMenuItem;
    Stop1: TMenuItem;
    N1: TMenuItem;
    Exit1: TMenuItem;
    Preference2: TMenuItem;
    Button2: TButton;
    Image1: TImage;
    procedure ServerSocket1ClientRead(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Preference1Execute(Sender: TObject);
    procedure ServerSocketPortChange(Sender: TObject);
    procedure ServerStart1Execute(Sender: TObject);
    procedure ServerStop1Execute(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
    BitMap: Graphics.TBitmap;
    DC: TCanvas;
    R1: TRect;
    ms: TMemoryStream;
  public
    { Public declarations }
  end;

var
  MainForm: TMainForm;

implementation

uses fPreffForm;

{$R *.dfm}

procedure TMainForm.ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
var
  s: String;

begin
  s := Socket.ReceiveText;
  if s='D' then begin
    BitMap.Canvas.CopyRect(R1, DC, R1);
    Image1.Picture.Bitmap := BitMap;
    Image1.Picture.Graphic.SaveToStream(ms);
    ms.Position := 0;
    Socket.SendStream(ms);
    ms.Clear;
  end;
end;

procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  if ServerStop1.Enabled then ServerStop1.Execute;
end;

procedure TMainForm.Preference1Execute(Sender: TObject);
begin
  PreffForm.ShowModal;
end;

procedure TMainForm.ServerSocketPortChange(Sender: TObject);
begin
  if ServerSocket1.Active then
   begin
     ServerStop1.Execute;
     ServerSocket1.Port := PreffForm.Port;
     ServerStart1.Execute;
   end
  else ServerSocket1.Port := PreffForm.Port;
end;

procedure TMainForm.ServerStart1Execute(Sender: TObject);
begin
  ServerSocket1.Active := True;
  StatusBar1.SimpleText := Format('Status: Runing on %d port',[ServerSocket1.Port]);
  ServerStart1.Enabled := False;
  ServerStop1.Enabled := True;
end;

procedure TMainForm.ServerStop1Execute(Sender: TObject);
begin
  ServerSocket1.Active := False;
  StatusBar1.SimpleText := 'Status: Stoped';
  ServerStart1.Enabled := True;
  ServerStop1.Enabled := False;
end;

procedure TMainForm.FormCreate(Sender: TObject);
begin
  R1 := Rect(0,0,Monitor.Width, Monitor.Height);
  DC := TCanvas.Create;
  DC.Handle := GetDC(0);
  BitMap := TBitmap.Create;
  BitMap.Width := R1.Bottom;
  BitMap.Height := R1.Right;
  ms := TMemoryStream.Create;
  ServerStart1.Execute;
end;

procedure TMainForm.FormDestroy(Sender: TObject);
begin
  ms.Free;
  BitMap.Free;
  DC.Free;
end;

end.


Клиент:
Код

unit UClientMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ScktComp, ExtCtrls;

type
  TForm1 = class(TForm)
    ClientSocket1: TClientSocket;
    Memo1: TMemo;
    btnConnect: TButton;
    edSendText: TEdit;
    edAdress: TEdit;
    edPort: TEdit;
    btnSend: TButton;
    edName: TEdit;
    Image1: TImage;
    procedure btnSendClick(Sender: TObject);
    procedure btnConnectClick(Sender: TObject);
    procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
    procedure FormDestroy(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    FNick: String;
    ms: TMemoryStream;
    procedure SetNick(const Value: String);
  public
    { Public declarations }
    property Nick: String read FNick write SetNick;
  end;

var
  Form1: TForm1;
//  Nick : string;
  
implementation

{$R *.dfm}

procedure TForm1.btnSendClick(Sender: TObject);
begin
  ClientSocket1.Socket.SendText('D');
end;

procedure TForm1.btnConnectClick(Sender: TObject);
begin
  ClientSocket1.Host    := edAdress.Text;
  ClientSocket1.Port    := StrToInt(edPort.Text);
  Nick := edName.Text;
  if not ClientSocket1.Active then ClientSocket1.Active := true;
  edName.Enabled        := false;
  edAdress.Enabled      := false;
  edport.Enabled        := false;
  btnConnect.Enabled    := false;
end;

procedure TForm1.ClientSocket1Read(Sender: TObject;
  Socket: TCustomWinSocket);
var
  buf: PByte;
  len: Integer;
begin
  len := Socket.ReceiveLength;
  buf := GetMemory(len);
  Socket.ReceiveBuf(buf, len);
  ms.Position := 0;
  ms.WriteBuffer(buf, len);
  ms.Position := 0;
  Image1.Picture.Graphic.LoadFromStream(ms);
  FreeMemory(buf);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  ms.Free;
  ClientSocket1.Active := false;
  ClientSocket1.Close;
  Close;
end;

procedure TForm1.SetNick(const Value: String);
begin
  FNick := Value;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  ms := TMemoryStream.Create;
end;

end.

там еще у сервера 2 форма с предполагаемыми настройками сервера...
Надеюсь понятно, что я копирую рабочий стол на канву битмапа, сохраняю в поток и отправляю клиенту...

Добавлено через 2 минуты и 12 секунд
Некоторые участки были написаны с использованием Delphi Russian Knowledge Base...

Добавлено через 11 минут и 7 секунд
а переменные ms, DC и BitMap не локальные для того, чтобы не тратить время на их создание и уничтожение при каждом обтащении клиета
PM MAIL ICQ   Вверх
Snowy
Дата 2.5.2007, 13:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 53
Всего: 484



Просто для теста, создай стрим локально, загрузи в него битмап с диска и отправь.
PM MAIL   Вверх
Saygak
  Дата 2.5.2007, 15:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 2.5.2007

Репутация: нет
Всего: 1



все время возился...
нашел, только что ClientCoket получает данные порциями (у меня 4096 б). Попробовал исправить передачу и получение данных. 
Сначала отправляю строку на сервере:
Код

...
Socket.SendText('Size:'+IntToStr(MemoryStream.Size)+#0);
Socket.SendStream(MemoryStream);
...


На клиенте:
Код

...
var
  s, s1: String;
begin
try
  s := ClientSocket1.Socket.ReceiveText;
  if Reciving then
   begin
     ms.Write(s[1], length(s));
     if ms.Size = DataSize then
      begin
        Reciving := False;
        BitMap.LoadFromStream(ms);  //Все равно в этой строке не сохраняется данные
        ms.Free;
        Image1.Picture.Bitmap := BitMap;
        BitMap.SaveToFile('temp.bmp'); // т.к. получаемый файл нулевой длинны...
      end;
   end
  else if copy(s, 1, 5)='Size:' then
   begin
     s1 := copy(s, 6, Pos(#0, s)-6);
     DataSize := StrToInt(s1);
     Delete(s, 1,Pos(#0, s));
     Reciving := true;
     ms := TMemoryStream.Create;
     ms.Write(s[1], length(s));
   end;
...

(код подсмотрел в книге "Программирование в Delphi глазами хакера")
 smile 
Snowy, инициализация переменных внутри процедур (локально) у меня ничего не дает. Теперь ситуация такая: Данные передает (вродебы), но куда они деваются непонятно...
PS. Как говорил один из пилотов: "Ничего не понимаю"... smile 
PM MAIL ICQ   Вверх
Saygak
Дата 2.5.2007, 16:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 2.5.2007

Репутация: нет
Всего: 1



фух, работает. 
Snowy, спасибо за совет:
Цитата
создай стрим локально, загрузи в него битмап с диска и отправь

Не сразу догадаешься, что этот стрим сам удаляется (наверно)...
А получать данные пришлось всетаки как я указывал раньше (по частям)...
программы вроде работают и ладно, будем улучшать...
PM MAIL ICQ   Вверх
Misha_White
Дата 14.5.2007, 11:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 25.4.2007
Где: Кодинск

Репутация: нет
Всего: 1



Такая же проблема... А Картинку нельзя как картинку отправить? Типа TJPEGImage? И как отправить через TSocket  операцией Send а получить Recv? Вроде отправляет и получает, но при попытке обращения пишет ошибку доступа к памяти... Помогите пожалуйста... Курсовик горит... 
--------------------
Я не волшебник... я только учусь...  
PM MAIL ICQ Skype   Вверх
Snowy
Дата 14.5.2007, 11:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 53
Всего: 484



Нет. Объект отправить нельзя.
Нужно сохранить в стрим и отправлять стрим.
Потом получить стрим и загрузить.
PM MAIL   Вверх
Misha_White
Дата 14.5.2007, 11:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 25.4.2007
Где: Кодинск

Репутация: нет
Всего: 1



Со стримом такая же система... Уже замучился...

Добавлено через 1 минуту и 38 секунд
При получении не ругается, а при попытке загрузки из стрима - ошибка... smile 
--------------------
Я не волшебник... я только учусь...  
PM MAIL ICQ Skype   Вверх
Snowy
Дата 14.5.2007, 11:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 53
Всего: 484



Значит неправильно передал или принял стрим.
PM MAIL   Вверх
Misha_White
  Дата 14.5.2007, 11:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 25.4.2007
Где: Кодинск

Репутация: нет
Всего: 1



JpegIm:=TJPEGImage.Create;
   MyStream:=TMemoryStream.Create;
  err:= recv(cSocket,MyStream,SizeOf(MyStream),0);
   If Err=Socket_Error then
    MessageBox(NULL,'Ошибка при получении!','Error',MB_OK);
   // MyStream.Seek(0,soFromBeginning);
    JpegIm.LoadFromStream(MyStream); // Здесь ругается!!!
   Image1.Picture.Assign(JpegIm);
   MyStream.Destroy;
   JpegIm.Destroy;

А как?

Добавлено @ 11:57
Записи же отправляются...

Это сообщение отредактировал(а) Misha_White - 14.5.2007, 12:03
--------------------
Я не волшебник... я только учусь...  
PM MAIL ICQ Skype   Вверх
Misha_White
Дата 14.5.2007, 12:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 25.4.2007
Где: Кодинск

Репутация: нет
Всего: 1



 smile 
--------------------
Я не волшебник... я только учусь...  
PM MAIL ICQ Skype   Вверх
Snowy
Дата 14.5.2007, 12:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 53
Всего: 484



Круто  smile 
Я ошибся - оказывается ты неправильно передаёшь и неправильно принимаешь smile
Я ж тебе говорю - нельзя передавать объекты.
Разницу между объектом и записью ощущаешь?
Тебя не смущает, что SizeOf(MyStream) равно 4 байта?
В твоём коде вообще всё неправильно. 
Нужно отправлять размер картинки перед передачей.
Перед приёмом нужно подготовить буфер и читать в него.
Причём, как передавать, так и читать нужно не объект, а данные.
Для MemoryStream это Memory и Size.
Посмотри хотя бы код в этом топике.
Почитай пример передачи картинки в DRKB
Попробуй поиск - передача картинки или файла обсуждалась неоднократно.

Добавлено через 3 минуты и 20 секунд
http://forum.vingrad.ru/forum/topic-112719/index.html
PM MAIL   Вверх
Misha_White
Дата 14.5.2007, 12:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 25.4.2007
Где: Кодинск

Репутация: нет
Всего: 1



Спасибо, о сенсей! Че-то ничего не могу понять... Ща попробую поиск...
--------------------
Я не волшебник... я только учусь...  
PM MAIL ICQ Skype   Вверх
Snowy
Дата 14.5.2007, 12:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 53
Всего: 484



Я ж тебе уже всё нашёл и линк дал  smile 
PM MAIL   Вверх
Misha_White
Дата 14.5.2007, 12:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 25.4.2007
Где: Кодинск

Репутация: нет
Всего: 1



Спасибо! Ща буду разбираться... Сколько уже мучаюсь... В книжках только по TserverSocket and TClientSocket... и там вроде есть Метод SendStream... А их не использую... А DRKB, блин, 30 метров весит... Я его неделю буду качать... :-(

Добавлено через 13 минут и 50 секунд
Как все запущено... smile 
--------------------
Я не волшебник... я только учусь...  
PM MAIL ICQ Skype   Вверх
Misha_White
Дата 14.5.2007, 13:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 25.4.2007
Где: Кодинск

Репутация: нет
Всего: 1



 smile 
--------------------
Я не волшебник... я только учусь...  
PM MAIL ICQ Skype   Вверх
Saygak
Дата 14.5.2007, 13:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 2.5.2007

Репутация: нет
Всего: 1



Привет Misha_White, у меня тоже была проблема. Тебе надо отправлять картинку?
Я уже ковырятся с этим. Как я делаю:
в событии OnRead у ServerSocket
 - сохряняю картинку в стрим (у меня TMemoryStream)
 - оправляю строку 'Size:'+TStream.Size+#0; (Socket.SendText(...))
 - потом отправляю стрим (Soket.SendStream(...))(не вызывай после этой строки метод Free стрима)

на клиенте при OnRead у ClientSocket
 - получаю строку (например 'Size:4000'#0) создаю TMemoryStream, строковую переменную, и инициализирую переменные (размер получаемых данных(DataSize из строки 'Size:4000'#0), и логическую переменную(Recived) что начат прием данных). при слудующем приеме данных если
Recived = true тогда записываю данные из полученной строки в стрим, как только размер полученных данных (TStream.Size) равен размеру получаемых данных (DataSize) загружаю картинку из стрима.

Все. smile
PM MAIL ICQ   Вверх
Misha_White
Дата 14.5.2007, 13:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 25.4.2007
Где: Кодинск

Репутация: нет
Всего: 1



Saygak, 
Спасибо! Но я не использую TServerSocket! У меня сокет типа TSocket... Отправлять могу только Send(), а получать Recv()... Вот такая проблема... smile 
--------------------
Я не волшебник... я только учусь...  
PM MAIL ICQ Skype   Вверх
Misha_White
Дата 14.5.2007, 16:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 25.4.2007
Где: Кодинск

Репутация: нет
Всего: 1



Snowy,  
Если сначала отправлять размер картинки... и что, следом слать саму картинку? Но как узнать, что получать? Т.е. я же не знаю, картинка это или нет... Допустим мы сохраним размер в Integer переменной и отправим и что, сразу шлем картинку(стрим)? А в клиенте подрят получаем сначала размер стрима и следом сразу стрим что ли? Че-то ниче не пойму...
--------------------
Я не волшебник... я только учусь...  
PM MAIL ICQ Skype   Вверх
Snowy
Дата 14.5.2007, 16:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 53
Всего: 484



Да, отправляем сначала размер стрима - 4 байта.
Потом сразу данные, указанного размера.
А клиент сидит и ждёт, пока ему пришлют 4 байта.
Получает, выделяет буфер и начинает читать, пока не прочитает указанное кол-во байт.
PM MAIL   Вверх
Misha_White
Дата 15.5.2007, 01:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 25.4.2007
Где: Кодинск

Репутация: нет
Всего: 1



Цитата

Да, отправляем сначала размер стрима - 4 байта.


Почему именно 4 байта? Если Stream.Size=~64134, если это размер моего стрима, то почму нельзя указать его?

Цитата

А клиент сидит и ждёт, пока ему пришлют 4 байта.

Как этого добиться? smile 
У меня клиент в это время должен отправлять свои данные этому серверу... А если подрят вызывать Recv, то ерунда же получится...

CЕРВЕР
Код

procedure SendDisp;
Var Error:integer;
    DispSize:integer;
  //  DispStream:TMemoryStream;
begin
DispStream:=TMemoryStream.Create;
 JpegIm.SaveToStream(DispStream);
   DispStream.Seek(0,soFromBeginning);
  DispSize:=DispStream.Size;
 if vSocket<>Socket_Error then
  begin
   Error:=Send(vSocket,DispSize,SizeOf(DispSize),0);
      Error:=Send(vSocket,DispStream,DispSize,0);
       DispStream.Clear;
     JpegIm.Destroy;
   if Error=Socket_Error then
    begin
      ServerForm.Timer1.Enabled:=False;
       MessageDlg('Ошибка при передаче данных!',mtWarning,[mbOk],0);
    end;
  end
 else
  MessageDlg('Ошибка при передаче данных! Socket_Error',mtWarning,[mbOk],0);
end;


КЛИЕНТ
Код

procedure TClientForm.Socket_Proc_Read_Close(var Msg:TMessage);
Var err:integer;
begin
 if WSAGETSELECTEVENT(Msg.lParam) = FD_CLOSE then
  begin
   MessageDlg('Сервер закрыл соединение',mtInformation,[mbOk],0);
   ClientForm.Caption:='RemAdmin - Disconnected';
   ClientForm.Button1.Enabled:=true;
  end;

 if WSAGETSELECTEVENT(Msg.lParam) = FD_READ then
  begin
   if Reciv=false then
    begin
     Err:=recv(cSocket,DispSize,SizeOf(DispSize),0);
     reciv:=true;
    end
   else
    begin
     JpegIm:=TJPEGImage.Create;
      MyStream:=TMemoryStream.Create;
       MyStream.SetSize(DispSize);
      MyStream.Position:=0;
     if DispSize<>0 then //DispSize=71123...
      err:= recv(cSocket,MyStream,DispSize,0); //В этом месте DispSize=-1!
       If Err=Socket_Error then
        MessageBox(NULL,'Ошибка при получении!','Error',MB_OK);
       MyStream.Position:=0;
        JpegIm.LoadFromStream(MyStream);
         Image1.Picture.Assign(JpegIm);
       MyStream.Destroy;
      JpegIm.Destroy;
     Reciv:=false;
    end;
   If Err=Socket_Error then
    MessageBox(NULL,'Ошибка при получении!','Error',MB_OK);
  end;

end;

Только не смейтесь пожалуйста, о сенсей! Как нужно сделать?

Это сообщение отредактировал(а) Misha_White - 15.5.2007, 02:20
--------------------
Я не волшебник... я только учусь...  
PM MAIL ICQ Skype   Вверх
Snowy
Дата 15.5.2007, 12:55 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 53
Всего: 484



уже лучше.

Цитата(Misha_White @  15.5.2007,  01:49 Найти цитируемый пост)
Почему именно 4 байта?
Потому что 4 байта - это до 2Гб данных.
Ты собираешься передавать данные большего размера?
Вряд ли... Да и 4 байта - основная еденица в 32-битных системах. С ней удобно работать.

Цитата(Misha_White @  15.5.2007,  01:49 Найти цитируемый пост)
У меня клиент в это время должен отправлять свои данные этому серверу... А если подрят вызывать Recv, то ерунда же получится...
Нет конечно. Нельзя вешаться.
Присасываться на приём нужно только по прибытии данных, иначе повиснешь наглухо.
Код
  ioctlsocket(SocketHandle, FIONREAD, size);
Этому коду скорми хэндл сокета и в size получишь кол-во данных в буфере сокета. Если 0, то читать нечего.

Цитата(Misha_White @  15.5.2007,  01:49 Найти цитируемый пост)
Error:=Send(vSocket,DispStream,DispSize,0);
Не компонент. Данные нужно передавать, и принимать соответственно. DispStream.Memory^, а не сам DispStream.
PM MAIL   Вверх
Misha_White
Дата 15.5.2007, 16:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 25.4.2007
Где: Кодинск

Репутация: нет
Всего: 1



Snowy, 
Цитата

Присасываться на приём нужно только по прибытии данных, иначе повиснешь наглухо.

А у меня процедурка TClientForm.Socket_Proc_Read_Close(var Msg:TMessage); вызывается только при прибытии данных или если поступило сообщение о закрытии сокета сервером!
Код

procedure Socket_Proc_Read_Close(var Msg:TMessage);message NETEVENT_MSG;

Т.е. сообщение NETEVENT_MSG; поступает от сервера только когда он передал данные, либо когда закрыл соединение...

Цитата(Snowy @  15.5.2007,  19:55 Найти цитируемый пост)
Цитата(Misha_White @  15.5.2007,  01:49 )
Error:=Send(vSocket,DispStream,DispSize,0);

Не компонент. Данные нужно передавать, и принимать соответственно. DispStream.Memory^, а не сам DispStream.

Т.е. нужно написать Send(vSocket,DispStream.Memory^,DispSize,0); и все начнет работать? А почему в Делфи у DispStream нету свойства(или метода) Memory? Т.е. DispStream.<Ctrl>+<Spase> ничего не дает? правда я не разыменовывал Memory и не компилировал... Но сейчас попробую...

Добавлено через 7 минут и 12 секунд
Snowy, 
 smile  Написал... Хоть кусок получил... Сказал, что Out of memory... Верхняя часть нормальная, а потом ужас... smile  Короче разноцветные полосы...

Это сообщение отредактировал(а) Misha_White - 15.5.2007, 16:06
--------------------
Я не волшебник... я только учусь...  
PM MAIL ICQ Skype   Вверх
Snowy
Дата 15.5.2007, 16:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 53
Всего: 484



Разумеется.
recv принимает только те данные, которые есть в буфере сокета.
Ты должен проверять - если принято меньше, чем указано байт, то нужно подождать, когда придут остальные данные и продолжить приём.
Это же не UDP - данные идут потоком, а не приходят за один раз.
Поэтому верх у тебя нормальный - он принялся.
А полосы ниже - мусор, вместо принятых данных.
Остальные данные должны были придти позже.
PM MAIL   Вверх
Misha_White
  Дата 15.5.2007, 16:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 25.4.2007
Где: Кодинск

Репутация: нет
Всего: 1



Snowy, 
Спасибо! Завтра попробую... или сечас... уже поздно, надо спать... Т.е. получили кусок и вышли из процедуры?  Или заLOOPить прием стрима?

Это сообщение отредактировал(а) Misha_White - 15.5.2007, 16:37
--------------------
Я не волшебник... я только учусь...  
PM MAIL ICQ Skype   Вверх
Snowy
Дата 15.5.2007, 16:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 53
Всего: 484



Цитата(Misha_White @  15.5.2007,  16:36 Найти цитируемый пост)
Т.е. получили кусок и вышли из процедуры?  Или заLOOPить прием стрима?
Как хочешь.
Выбор стратегии за тобой.
PM MAIL   Вверх
Misha_White
Дата 15.5.2007, 16:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 25.4.2007
Где: Кодинск

Репутация: нет
Всего: 1



Snowy, 
 smile Ok, ща попробуем...  smile Надо комп второй заводить
--------------------
Я не волшебник... я только учусь...  
PM MAIL ICQ Skype   Вверх
Misha_White
  Дата 15.5.2007, 17:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 25.4.2007
Где: Кодинск

Репутация: нет
Всего: 1



Snowy, 
Код

if WSAGETSELECTEVENT(Msg.lParam) = FD_READ then
  begin
   if Reciv=false then
    begin
     Err:=recv(cSocket,DispSize,SizeOf(DispSize),0);
     reciv:=true;
    end
   else
    begin
     JpegIm:=TJPEGImage.Create;
      MyStream:=TMemoryStream.Create;
       MyStream.SetSize(DispSize);
      MyStream.Position:=0;
      StreamSize:=0;
     While DispSize<>StreamSize do
      begin
       err:= recv(cSocket,MyStream.Memory^,DispSize,0);
        StreamSize:=StreamSize+err;
        If Err=Socket_Error then
         begin
          MessageBox(NULL,'Ошибка при получении!','Error',MB_OK);
          Break;
         end;
      end;
       MyStream.Seek(0,soFromBeginning);
        JpegIm.LoadFromStream(MyStream); //Здесь ругается...
         Image1.Picture.Assign(JpegIm);
       MyStream.Destroy;
      JpegIm.Destroy;
     Reciv:=false;
    end;
   If Err=Socket_Error then
    MessageBox(NULL,'Ошибка при получении!','Error',MB_OK);
  end;


 smile Блин, уже голова не варит.... Помоги... Говорит, что ошибка с JPEG....
Не могу понять, то-ли я стрим не так принял или че... Ну размеры вроде совпадают... Вот думаю, может во время приема Seek-ать надо в конец полученного куска? Или все-таки с JPEG проблема?

Добавлено через 11 минут и 40 секунд
Snowy, 
Достал я тебя походу... Ладно, завтра буду разбираться с этим делом...

Это сообщение отредактировал(а) Misha_White - 15.5.2007, 17:53
--------------------
Я не волшебник... я только учусь...  
PM MAIL ICQ Skype   Вверх
Snowy
Дата 15.5.2007, 18:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 53
Всего: 484



Угу. Memory всегда указывает на начало стрима.
То есть ты постоянно перезаписываешь начало, а дальше не пишешь.
Заведи какой-нить буффер килобайта на 4, читай в него и скидывай в стрим, пока не накидаешь нужный размер.
В стрим скидывай через метод Write.
PM MAIL   Вверх
Misha_White
Дата 16.5.2007, 08:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 25.4.2007
Где: Кодинск

Репутация: нет
Всего: 1



Snowy, 
Че-т ничерта не пойму... А буфер какого типа брать? И как потом Write-ом кидать?  smile 
--------------------
Я не волшебник... я только учусь...  
PM MAIL ICQ Skype   Вверх
Snowy
Дата 16.5.2007, 10:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 53
Всего: 484



Любого. Например string отлично подходит.
Только сначала нужно ему длину определить SetLength(s, 4096);
А передавать recv и Write не сам стринг, а s[1]
PM MAIL   Вверх
Misha_White
Дата 16.5.2007, 10:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 25.4.2007
Где: Кодинск

Репутация: нет
Всего: 1



Misha_White, 
Понятно, попробую... А во Write надо вторым параметром Count передавать... Это и будет 4096?

Добавлено через 4 минуты и 24 секунды
Snowy, 
Или Столько, сколько возвратит Recv?

Добавлено через 8 минут и 32 секунды
Код

 JpegIm:=TJPEGImage.Create;
      MyStream:=TMemoryStream.Create;
       MyStream.SetSize(DispSize);
      MyStream.Position:=0;
      StreamSize:=0;
        SetLength(s,4096);
     While DispSize<>StreamSize do
      begin
       err:= recv(cSocket,S[1],DispSize,0);
        StreamSize:=StreamSize+err;
         MyStream.Write(S[1],err);

        If Err=Socket_Error then
         begin
          MessageBox(NULL,'Ошибка при получении!','Error',MB_OK);
          Break;
         end;
      end;
       MyStream.Seek(0,soFromBeginning);
        JpegIm.LoadFromStream(MyStream);
         Image1.Picture.Assign(JpegIm);
       MyStream.Destroy;
           JpegIm.Destroy;
     Reciv:=false;

Че-то не так.... smile

Добавлено через 11 минут и 6 секунд
 smile 
--------------------
Я не волшебник... я только учусь...  
PM MAIL ICQ Skype   Вверх
Snowy
Дата 16.5.2007, 10:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 53
Всего: 484



Цитата(Misha_White @  16.5.2007,  10:25 Найти цитируемый пост)
MyStream.SetSize(DispSize);

Цитата(Misha_White @  16.5.2007,  10:25 Найти цитируемый пост)
StreamSize:=StreamSize+err;

Убери установку размера стрима.
Он сам растянется по мере записи в него.

PM MAIL   Вверх
Misha_White
Дата 16.5.2007, 11:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 25.4.2007
Где: Кодинск

Репутация: нет
Всего: 1



Цитата(Snowy @  16.5.2007,  17:46 Найти цитируемый пост)
StreamSize:=StreamSize+err;

это - размер принятого... Чтобы сравнить с DispSize...

Цитата(Misha_White @  16.5.2007,  17:25 Найти цитируемый пост)
err:= recv(cSocket,S[1],DispSize,0);
        StreamSize:=StreamSize+err;
         MyStream.Write(S[1],err);

Во Write что писать? Err или 4096?



--------------------
Я не волшебник... я только учусь...  
PM MAIL ICQ Skype   Вверх
Snowy
Дата 16.5.2007, 11:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 53
Всего: 484



Цитата(Misha_White @  16.5.2007,  11:13 Найти цитируемый пост)
это - размер принятого... Чтобы сравнить с DispSize...
А зачем? У стрима уже есть Size.

Цитата(Misha_White @  16.5.2007,  11:13 Найти цитируемый пост)
Во Write что писать? Err или 4096?
err
PM MAIL   Вверх
Misha_White
  Дата 16.5.2007, 12:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 25.4.2007
Где: Кодинск

Репутация: нет
Всего: 1



Snowy, 
Я написал
Код

procedure TClientForm.Socket_Proc_Read_Close(var Msg:TMessage);
Var err:integer;
    S:String;
begin
 if WSAGETSELECTEVENT(Msg.lParam) = FD_CLOSE then
  begin
   MessageDlg('Сервер закрыл соединение',mtInformation,[mbOk],0);
    ClientForm.Caption:='RemAdmin - Disconnected';
   ClientForm.Button1.Enabled:=true;
  end;

 if WSAGETSELECTEVENT(Msg.lParam) = FD_READ then  //После приема всего стрима возвращаемся сюда...
  begin
   if Reciv=false then
    begin
     Err:=recv(cSocket,DispSize,SizeOf(DispSize),0);
      If Err=Socket_Error then
        MessageBox(NULL,'Ошибка при получении!','Error',MB_OK)
      else
     reciv:=true;
    end
   else
    begin
     JpegIm:=TJPEGImage.Create;
      MyStream:=TMemoryStream.Create;
       SetLength(s,4096);
     While DispSize<>MyStream.Size do
      begin
       err:= recv(cSocket,S[1],DispSize,0);
         MyStream.Write(S[1],err);
        If Err=Socket_Error then
         begin
           MessageBox(NULL,'Ошибка при получении!','Error',MB_OK);
           Break;
         end;
      end;
       MyStream.Seek(0,soFromBeginning);
        JpegIm.LoadFromStream(MyStream);
         Image1.Picture.Assign(JpegIm);
       MyStream.Destroy;
      JpegIm.Destroy;
     Reciv:=false;
    end;
  end;
end;

Но после приема стрима, прога не выходит из цикла, а начинает с начала приема данных (хотя с сервера ничего не отправлялось)и, считывая DispSize , выдает ошибки...

Это сообщение отредактировал(а) Misha_White - 16.5.2007, 12:32
--------------------
Я не волшебник... я только учусь...  
PM MAIL ICQ Skype   Вверх
Snowy
Дата 16.5.2007, 13:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 53
Всего: 484



Принимай не DispSize, а 4096!
У тебя мимо буфера выливается
PM MAIL   Вверх
Misha_White
Дата 16.5.2007, 13:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 25.4.2007
Где: Кодинск

Репутация: нет
Всего: 1



Snowy, 
Could not convert variant of type (Null) into (Int64)...

Добавлено через 41 секунду
Заругался клиент
--------------------
Я не волшебник... я только учусь...  
PM MAIL ICQ Skype   Вверх
Snowy
Дата 16.5.2007, 13:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 53
Всего: 484



В каком месте?
Поменяй условие цикла на >
Пиши в стрим только, если err > 0
PM MAIL   Вверх
Misha_White
Дата 16.5.2007, 13:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 25.4.2007
Где: Кодинск

Репутация: нет
Всего: 1



Snowy, 
Дело в том, что стрим записывается полностью, и картинка появляется, но процедура пытается еще считывать данные из сокета, а Reciv  у нас уже False, поэтому она пытается принять размер стрима... и так раза 4-5... потом только приходит новая картинка... походу...

Добавлено через 57 секунд
Snowy, 
Я Аську поставил... smile 
--------------------
Я не волшебник... я только учусь...  
PM MAIL ICQ Skype   Вверх
Snowy
Дата 16.5.2007, 14:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 53
Всего: 484



Это просто потому, что картинка шла несколькими частями.
А сокет у тебя асинхронный.
Вот и накопилась очередь сообщений о приходе данных.
О отрабатывает она только по выходу из обработчика.
Сразу выходи из обработчика, если в буфере пусто.
PM MAIL   Вверх
Misha_White
Дата 16.5.2007, 14:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 25.4.2007
Где: Кодинск

Репутация: нет
Всего: 1



Snowy, 
Каким Макаром?

Добавлено через 7 минут и 18 секунд
Snowy, 
Выйти из обработчика?
--------------------
Я не волшебник... я только учусь...  
PM MAIL ICQ Skype   Вверх
Snowy
Дата 16.5.2007, 15:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 53
Всего: 484



Exit
PM MAIL   Вверх
Misha_White
  Дата 16.5.2007, 15:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 25.4.2007
Где: Кодинск

Репутация: нет
Всего: 1



Snowy, 
Из обработчика... дело походу в том, что продолжает поступать сообщение NETEVENT_MSG... Вот... Поэтому процедура повторно(раз5-8) вызывается...
--------------------
Я не волшебник... я только учусь...  
PM MAIL ICQ Skype   Вверх
Snowy
Дата 16.5.2007, 15:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 53
Всего: 484



Разумеется вызывается.
Я даже написал почему.
А будет картинка большего размера - будет больше вызываться.
В самом начале обработчика вставь проверку на наличие данных в буфере.
Если данных 0, то сразу делай Exit;
PM MAIL   Вверх
Misha_White
  Дата 17.5.2007, 08:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 25.4.2007
Где: Кодинск

Репутация: нет
Всего: 1



Snowy, 
Сделал подругому!
Код

procedure TClientForm.Socket_Proc_Read_Close(var Msg:TMessage);
Var err:integer;
    S:String;
begin
 if WSAGETSELECTEVENT(Msg.lParam) = FD_CLOSE then
  begin
   MessageDlg('Сервер закрыл соединение',mtInformation,[mbOk],0);
   ClientForm.Caption:='RemAdmin - Disconnected';
   ClientForm.Button1.Enabled:=true;
  end;

 if WSAGETSELECTEVENT(Msg.lParam) = FD_READ then
  begin
   if Reciv=false then
    begin
     Err:=recv(cSocket,DispSize,SizeOf(DispSize),0);
      If Err=Socket_Error then
        MessageBox(NULL,'Ошибка при получении!','Error',MB_OK)
      else
       begin
        reciv:=true;
         MyStream:=TMemoryStream.Create;
        JpegIm:=TJPEGImage.Create;
       end;
    end
   else
    begin
       SetLength(s,17520);
       err:= recv(cSocket,S[1],17520,0);
        If Err=Socket_Error then
         begin
          MessageBox(NULL,'Ошибка при получении!','Error',MB_OK);
          exit;
         end;
       MyStream.Write(S[1],err);
    if DispSize=MyStream.Size then
     begin
       MyStream.Position:=0; //Seek(0,soFromBeginning);
        JpegIm.LoadFromStream(MyStream);
         Image1.Canvas.Draw(0,0,JpegIm);
        MyStream.Destroy;
          JpegIm.Destroy;
      Reciv:=false;
     end;
    end;
  end;

end;

но почему-то ругается при второй попытке... в строке
Код

JpegIm.LoadFromStream(MyStream);

Т.е., когда принимаем вторую картинку... Принимается вроде как надо(размеры совпадают)... а при попытке загрузить в Image рагается, блин
Не могу понять почему...

Это сообщение отредактировал(а) Misha_White - 17.5.2007, 09:32
--------------------
Я не волшебник... я только учусь...  
PM MAIL ICQ Skype   Вверх
Misha_White
Дата 17.5.2007, 11:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 25.4.2007
Где: Кодинск

Репутация: нет
Всего: 1



Snowy, 
 smile 
--------------------
Я не волшебник... я только учусь...  
PM MAIL ICQ Skype   Вверх
Misha_White
Дата 17.5.2007, 11:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 25.4.2007
Где: Кодинск

Репутация: нет
Всего: 1



Snowy, 
Есть идеи, почему так?
--------------------
Я не волшебник... я только учусь...  
PM MAIL ICQ Skype   Вверх
Misha_White
Дата 18.5.2007, 15:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 25.4.2007
Где: Кодинск

Репутация: нет
Всего: 1



Misha_White, 
Такой вопрос: почему передавать нужно S[1]? что это значит?
--------------------
Я не волшебник... я только учусь...  
PM MAIL ICQ Skype   Вверх
Snowy
Дата 18.5.2007, 16:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 53
Всего: 484



s[1] - первый символ. 
Это и есть начало буфера, поскольку сам стринг - указатель, а передать нужно буфер, а не указатель на него.
PM MAIL   Вверх
Misha_White
  Дата 18.5.2007, 16:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 25.4.2007
Где: Кодинск

Репутация: нет
Всего: 1



Snowy, 
Понятно. Спасибо! А я ведь так и не понял почему он второй раз не грузится... Сегодня в универе запустил на двух машинах, дак она с третьего раза не захотела загружаться... smile  Во прикол!
--------------------
Я не волшебник... я только учусь...  
PM MAIL ICQ Skype   Вверх
Misha_White
Дата 19.5.2007, 13:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 25.4.2007
Где: Кодинск

Репутация: нет
Всего: 1



Snowy,  Если ошибка возникает при третьем приеме, то она возникает при попытке создать стрим... smile 
--------------------
Я не волшебник... я только учусь...  
PM MAIL ICQ Skype   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Сети"
Snowy
Poseidon
MetalFan

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делится вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Snowy, Poseidon, MetalFan.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Сети | Следующая тема »


 




[ Время генерации скрипта: 0.1646 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.