CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - Paint przez sieć

Paint przez sieć

problemy z tworzeniem programów do obsługi sieci, internetu, e-mail itp..

Paint przez sieć

Nowy postprzez gregory » sobota, 22 stycznia 2011, 16:17

Witam.
Mam do napisania program a'la paint przez który wielu użytkowników może rysować jednocześnie przez sieć. Aplikacja jest zarówno klientem jak i serwerem. Używam TServerSocket i TClientSocket. Samo łączenie użytkowników z aplikacją jest już zaprogramowane. Do napisania zostało mi tylko przesyłanie tego co rysuje dany użytkownik, aby każdy u siebie widział postęp rysowania połączonych użytkowników(czyli aby każdemu użytkownikowi wyświetlało się w programie to co rysują inni użytkownicy). Niestety nie mam zbytnio pomysłu jak to należy zrobić. Proszę o pomoc.
Avatar użytkownika
gregory
Bladawiec
Bladawiec
 
Posty: 26
Dołączył(a): środa, 17 lutego 2010, 17:36
Podziękował : 8
Otrzymał podziękowań: 0
System operacyjny: Windows 7
Kompilator: C++ Builder
Gadu Gadu: 0
    Windows 7Firefox

Re: Paint przez sieć

Nowy postprzez ppc8867 » sobota, 22 stycznia 2011, 22:59

Podaj kod jaki już masz to coś poradzimy dalej.
Avatar użytkownika
ppc8867
Bladawiec
Bladawiec
 
Posty: 10
Dołączył(a): sobota, 22 stycznia 2011, 22:18
Podziękował : 1
Otrzymał podziękowań: 0
System operacyjny: brak systemu
Kompilator: C++ Builder 2009
C++ Builder 6
Gadu Gadu: 0
    Windows 7Firefox

Re: Paint przez sieć

Nowy postprzez gregory » niedziela, 23 stycznia 2011, 11:30

Oto kod całego programu.
KOD cpp:     UKRYJ  
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Main.h"
#include "Options.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
enum TStanRys {start, koniec} StanRys;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
        PaintBox1->Canvas->Pen->Width = 3;
        StanRys = koniec;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Shape1MouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift,
          int X, int Y)
{
        if (ColorDialog1->Execute())
        {
                Shape1->Brush->Color = ColorDialog1->Color;
                PaintBox1->Canvas->Pen->Color = Shape1->Brush->Color;
        }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::PedzelButtonClick(TObject *Sender)
{
        PaintBox1->Canvas->Pen->Color = Shape1->Brush->Color;
        PaintBox1->Canvas->Pen->Width = 3;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::PaintBox1MouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift,
          int X, int Y)
{
    PaintBox1->Canvas->FloodFill(X, Y,0 , fsSurface);
        if (PedzelButton->Down || GumkaButton->Down )
        {
                StanRys = start;
                PaintBox1->Canvas->MoveTo(X, Y);
                PaintBox1->Canvas->Pen->Mode = pmCopy;

        }
        else if (LiniaButton->Down)
        {
                switch(StanRys)
                {
                case start:
                StanRys = koniec;
                PaintBox1->Canvas->Pen->Mode = pmCopy;
                PaintBox1->Canvas->MoveTo(XPocz, YPocz);
                PaintBox1->Canvas->LineTo(X, Y);
                break;
                case koniec:
                StanRys = start;
                PaintBox1->Canvas->Pen->Mode = pmNotXor;
                XPocz = X;
                YPocz = Y;
                Xr = X;
                Yr = Y;
                break;
                }
        }
        else if(ElipsaButton->Down)
        {
        StanRys = start;
                XPocz = X;
                YPocz = Y;
                Xr = X;
                Yr = Y;
        }
}
//---------------------------------------------------------------------------

void __fastcall TForm1::PaintBox1MouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift,
          int X, int Y)
{

        if( WiadroButton->Down)
        {
                PaintBox1->Canvas->Brush->Color = Shape1->Brush->Color;
                PaintBox1->Canvas->FloodFill(X, Y,Shape1->Brush->Color , fsBorder);
        }
        StanRys = koniec;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::PaintBox1MouseMove(TObject *Sender, TShiftState Shift, int X,
          int Y)
{
                if(StanRys == start)
                {
                        if (PedzelButton->Down || GumkaButton->Down )
                        {
                                PaintBox1->Canvas->LineTo(X, Y);
                        }
                        else if (LiniaButton->Down)
                        {
                                PaintBox1->Canvas->MoveTo(XPocz, YPocz);
                                PaintBox1->Canvas->LineTo(Xr, Yr);
                                PaintBox1->Canvas->MoveTo(XPocz, YPocz);
                                PaintBox1->Canvas->LineTo(X, Y);
                                Xr = X;
                                Yr = Y;
                        }
                        else if (ElipsaButton->Down)
                        {
                                PaintBox1->Canvas->Pen->Mode = pmNotXor;
                                PaintBox1->Canvas->Pen->Style = psSolid;
                                PaintBox1->Canvas->Ellipse(XPocz, YPocz, Xr, Yr);
                                PaintBox1->Canvas->Ellipse(XPocz, YPocz, X, Y);
                                Xr = X;
                                Yr = Y;
                                PaintBox1->Canvas->Pen->Mode = pmCopy;
                        }
                }
}
//---------------------------------------------------------------------------

void __fastcall TForm1::GumkaButtonClick(TObject *Sender)
{
        PaintBox1->Canvas->Pen->Color = clWhite;
        PaintBox1->Canvas->Pen->Width = 10;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Wyczywszystko1Click(TObject *Sender)
{
        PaintBox1->Refresh();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Oprogramie1Click(TObject *Sender)
{
        MessageBoxA(0,"NetPaint 0.99 \nAutor: ****", "Informacje o autorze", MB_OK | MB_ICONINFORMATION);
}
//---------------------------------------------------------------------------


void __fastcall TForm1::PołączClick(TObject *Sender)
{
        Panel3->Visible = true;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::ZamknijClick(TObject *Sender)
{
        Close();
}
//---------------------------------------------------------------------------


void __fastcall TForm1::Button1Click(TObject *Sender)
{
        int port;

        if (TryStrToInt(Edit2->Text, port) && Edit1->Text != "")
        {
                ClientSocket1->Host = Edit1->Text;
                ClientSocket1->Port = port;
                ClientSocket1->Active = true;
        }
        else
        {
                MessageBoxA(this->Handle, "Wprowadź port i adres hosta", "Błąd!", MB_OK | MB_ICONERROR);
        }

}
//---------------------------------------------------------------------------

void __fastcall TForm1::RozłączClick(TObject *Sender)
{
        ClientSocket1->Active = false;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::UruchomClick(TObject *Sender)
{
        ServerSocket1->Active = true;
        Caption = Caption + " - Serwer uruchomiony";

}
//---------------------------------------------------------------------------

void __fastcall TForm1::StopClick(TObject *Sender)
{
        ListBox1->Clear();
        ServerSocket1->Active = false;
        Caption = "NetPaint - Serwer wyłączony";
        Stop->Enabled = false;
        Uruchom->Enabled = true;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::OpcjeClick(TObject *Sender)
{
        Form2->ShowModal();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::ServerSocket1ClientConnect(TObject *Sender, TCustomWinSocket *Socket)

{
        ListBox1->Items->Append("Użytkownik " + Socket->RemoteAddress + ":" + Socket->RemotePort);
}
//---------------------------------------------------------------------------

void __fastcall TForm1::UruchomMouseEnter(TObject *Sender)
{
        StatusBar1->Panels->Items[0]->Text = dynamic_cast<TControl *>(Sender)->Name;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::ServerSocket1ClientDisconnect(TObject *Sender, TCustomWinSocket *Socket)

{
        ListBox1->Items->Delete(ListBox1->Items->IndexOf(
        Socket->RemoteAddress + ":" + Socket->RemotePort));
}
//---------------------------------------------------------------------------

void __fastcall TForm1::ServerSocket1Listen(TObject *Sender, TCustomWinSocket *Socket)

{
        Stop->Enabled = true;
        Uruchom->Enabled = false;
}
//---------------------------------------------------------------------------
 
Avatar użytkownika
gregory
Bladawiec
Bladawiec
 
Posty: 26
Dołączył(a): środa, 17 lutego 2010, 17:36
Podziękował : 8
Otrzymał podziękowań: 0
System operacyjny: Windows 7
Kompilator: C++ Builder
Gadu Gadu: 0
    Windows 7Firefox

Re: Paint przez sieć

Nowy postprzez Cyfrowy Baron » niedziela, 23 stycznia 2011, 12:06

W przypadku tego programu potrzebna jest jakaś koncepcja wymiany danych na bieżąco pomiędzy użytkownikami. Nie może się to odbywać po każdej zmianie w zawartości PaintBox, gdyż program by nie wyrobił, więc musiałoby się to odbywać po zapisaniu zmian, ale szczerze mówiąc nie mam pojęcia jak to zsynchronizować. Po zapisaniu zmian przez jednego użytkownika program musiałby porównać zawartość PaintBox wszystkich pozostałych użytkowników i nanieść na wspólny obiekt wszystko to co narysowali inni. Koszmar! Gdy zastanawiam się nad podobnym programem to przychodzą mi na myśl gdy działające w trybie multiplayer, ale te gdy nie zmieniają całej zawartości ekranu, a tylko fragment grafiki kontrolowany przez użytkownika, czyli z reguły jest to jakaś pojedyncza postać z gry, a więc tylko pojedynczy element graficzny, na który inni gracze nie mają wpływu, a obszar gry - tło pozostaje niezmienne dla wszystkich.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Paint przez sieć

Nowy postprzez ppc8867 » niedziela, 23 stycznia 2011, 13:27

A czy można pomiędzy klientem a serwerem przekazać strukturę albo np tablice int tab[2] ???
Wiem ze można przekazać tekst Socket->SendText();
Avatar użytkownika
ppc8867
Bladawiec
Bladawiec
 
Posty: 10
Dołączył(a): sobota, 22 stycznia 2011, 22:18
Podziękował : 1
Otrzymał podziękowań: 0
System operacyjny: brak systemu
Kompilator: C++ Builder 2009
C++ Builder 6
Gadu Gadu: 0
    Windows 7Firefox

Re: Paint przez sieć

Nowy postprzez polymorphism » niedziela, 23 stycznia 2011, 13:34

Metoda SendBuf.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Paint przez sieć

Nowy postprzez ppc8867 » niedziela, 23 stycznia 2011, 13:40

A mógłbyś podpowiedzieć jak to zapisać ?

np:

struct pakiet{
String wiadomosc;
int x,y;
}

------------------------

Socket->ReceiveBuf(pakiet,size(pakiet)); ??
Avatar użytkownika
ppc8867
Bladawiec
Bladawiec
 
Posty: 10
Dołączył(a): sobota, 22 stycznia 2011, 22:18
Podziękował : 1
Otrzymał podziękowań: 0
System operacyjny: brak systemu
Kompilator: C++ Builder 2009
C++ Builder 6
Gadu Gadu: 0
    Windows 7Firefox

Re: Paint przez sieć

Nowy postprzez gregory » niedziela, 23 stycznia 2011, 13:55

Wpadłem na taki pomysł, żeby rysować po obiekcie TImage i przesyłać do każdego użytkownika obraz np w postaci bitmapy i przypisywać go do komponentu TImage właśnie. Co sądzicie o takim rozwiązaniu? Ma to sens? A może są jakieś inne koncepcje bo póki co to nie wiem jak to rozwiązać? :roll:
Avatar użytkownika
gregory
Bladawiec
Bladawiec
 
Posty: 26
Dołączył(a): środa, 17 lutego 2010, 17:36
Podziękował : 8
Otrzymał podziękowań: 0
System operacyjny: Windows 7
Kompilator: C++ Builder
Gadu Gadu: 0
    Windows 7Firefox

Re: Paint przez sieć

Nowy postprzez polymorphism » niedziela, 23 stycznia 2011, 13:57

Socket->ReceiveBuf(pakiet,size(pakiet)); ??

Nie, tak nie możesz, bo jest tam typ String, którego nie możesz w ten sposób zapisać. Musisz zserializować tę klasę:

KOD cpp:     UKRYJ  
int n = wiadomosc.Length();
Socket->ReceiveBuf(&n,sizeof(n)); // zapisujesz długość stringa
Socket->ReceiveBuf(wiadomość.c_str(),n); // ...i samego stringa (zakładam, że c_str() zwraca char*)
 


Zasadniczo odradzam wysyłanie/zapisywanie struktur, bo więcej z tym problemów niż pożytku.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Paint przez sieć

Nowy postprzez ppc8867 » niedziela, 23 stycznia 2011, 13:58

Ja myślę aby przekazać strukturę w której można wysłać więcej niż tylko bitmapę. np kolor w jakim się rysowało kreskę

Ale nie wiem jak zapisac SendBuf
Avatar użytkownika
ppc8867
Bladawiec
Bladawiec
 
Posty: 10
Dołączył(a): sobota, 22 stycznia 2011, 22:18
Podziękował : 1
Otrzymał podziękowań: 0
System operacyjny: brak systemu
Kompilator: C++ Builder 2009
C++ Builder 6
Gadu Gadu: 0
    Windows 7Firefox

Re: Paint przez sieć

Nowy postprzez ppc8867 » niedziela, 23 stycznia 2011, 14:11

Kod: Zaznacz cały
void __fastcall TForm1::ClientSocket1Read(TObject *Sender,
      TCustomWinSocket *Socket)
{
// obbieranie i wyswietlenie

         String wiadomosc;
         int n = wiadomosc.Length();
         Socket->ReceiveBuf(&n,sizeof(n));
         Socket->ReceiveBuf(wiadomosc.c_str(),n);
         ShowMessage(wiadomosc);
}


Kod: Zaznacz cały
//wysylanie np w onClick dla przycisku
String a="siemka";
ClientSocket1->Socket->SendBuf(a, a..Length());


dobrze mysle ?
a jak bedzie dla serwera ?
Avatar użytkownika
ppc8867
Bladawiec
Bladawiec
 
Posty: 10
Dołączył(a): sobota, 22 stycznia 2011, 22:18
Podziękował : 1
Otrzymał podziękowań: 0
System operacyjny: brak systemu
Kompilator: C++ Builder 2009
C++ Builder 6
Gadu Gadu: 0
    Windows 7Firefox

Re: Paint przez sieć

Nowy postprzez polymorphism » poniedziałek, 24 stycznia 2011, 11:57

KOD cpp:     UKRYJ  
Socket->ReceiveBuf(wiadomosc.c_str(),n);

Nie możesz tak zrobić, ponieważ c_str zwraca wskaźnik na pamięć tylko do odczytu. Jeśli już, to np. tak:
KOD cpp:     UKRYJ  
...

char buf[256];
int read;

while(n > 0 && (read = Socket->ReceiveBuf(buf, min(n,255)) != -1)
{
        buf[read] = '\0'; // musi być c-string, ponieważ gówniany AnsiString nie ma podstawowych metod
        wiadomosc += buf;
        n -= read;
}
 



KOD cpp:     UKRYJ  
//wysylanie np w onClick dla przycisku
String a="siemka";
ClientSocket1->Socket->SendBuf(a, a..Length());

Co to jest? Przecież pokazywałem, jak wysłać Stringa!




Kody wstawiaj w znacznik CPP:
Kod: Zaznacz cały
[CPP]  tu kod   [/CPP]
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Paint przez sieć

Nowy postprzez polymorphism » poniedziałek, 24 stycznia 2011, 12:18

gregory napisał(a):Co sądzicie o takim rozwiązaniu? Ma to sens?

Słabe, niepotrzebnie obciąża łącze. Wysyłaj komendy, które będą instruowały pozostałe aplikacje co, gdzie i jak mają rysować. Dla lepszego zobrazowania idei dobry będzie przykład gry w statki. Żeby przeciwnikowi powiedzieć w które miejsce strzelasz, nie musisz podawać całej planszy z narysowanym punktem, wystarczy, że podasz współrzędne tego punktu. I w analogiczny sposób zrealizuj to u siebie.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Paint przez sieć

Nowy postprzez gregory » poniedziałek, 24 stycznia 2011, 13:03

polymorphism napisał(a):Słabe, niepotrzebnie obciąża łącze. Wysyłaj komendy, które będą instruowały pozostałe aplikacje co, gdzie i jak mają rysować. Dla lepszego zobrazowania idei dobry będzie przykład gry w statki. Żeby przeciwnikowi powiedzieć w które miejsce strzelasz, nie musisz podawać całej planszy z narysowanym punktem, wystarczy, że podasz współrzędne tego punktu. I w analogiczny sposób zrealizuj to u siebie.

A czy mógłbyś dać przykład kodu jak np przesłać rysowanie linii do wszystkich podłączonych użytkowników? Bo póki co ciężko mi to zrealizować.
Avatar użytkownika
gregory
Bladawiec
Bladawiec
 
Posty: 26
Dołączył(a): środa, 17 lutego 2010, 17:36
Podziękował : 8
Otrzymał podziękowań: 0
System operacyjny: Windows 7
Kompilator: C++ Builder
Gadu Gadu: 0
    Windows 7Firefox

Re: Paint przez sieć

Nowy postprzez polymorphism » poniedziałek, 24 stycznia 2011, 13:20

O szczegóły implementacyjne pytaj się kogoś, kto używa C++ Buildera.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Następna strona

  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Aplikacje sieciowe

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 3 gości

cron